/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package main;

import java.io.IOException;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

/**
 *
 * @author Administrator
 */
public class PhomScene extends CardGameScene implements IGameDisplay {

    private static final int TIME_FOR_THINK = 30;
    private static final int NUMBER_CARD_IN_HANDS = 11;
    private static final int DISTANCE_VERTICAL_CARD = 25;
    private static final int MARK_SET_COLOR = 0x0050a8;
    private static final int FLUSH_SET = 1;
    private static final int PAIR_SET = 2;
    private static final int CHOOSE_PAIR = 1;
    private static final int CHOOSE_FLUSH = 2;
    private static final int CHOOSE_ALL = 3;
    //--------------------------------------------------------------------
    private boolean isDrawMarkPhomSet;
    private boolean isDepositCard;
    private boolean isShowPlayerName;
    private boolean isDrawResult;
    private boolean isGetMoreCard;
    private boolean isHaPhom;
    private boolean isMoveDrawCard;
    private boolean isEatCard;
    private boolean isMoveBcCard;
    private boolean showRemainCard;
//-------------------------------------------------------------------------------
    private int playerWinByUId;
    private int firstHaPhom;
    private int cardEatedIndex1;
    private int cardEatedIndex0;
    private int cardEatedIndex2;
    private int cardEatedIndex3;
    private int cardMoveIndex;
    private int depositTargerIndex;
    private int depositCardIndex;
    private int playerFightid;
//    private int phomIdArrIndex;
    private int gameRule;
    private int depositTargerListLength;
    private int playerEatId;
    private int numberPlayersStart;
    private int cardBcId;
    //private int startSetIndex;
    private int playeIdWin;
    private int countFnReceive;
    private int eatSetType;
    private int numberEats;
    private int numberPairs;
    private int numberFlushs;
    private int numberPhoms;
    private boolean isHavePhom;
    private boolean isDrawClock;
//    private int startSetIndex;
//----------------------------------------------------------------------------
    private Image boxCenterTable;
    private Image doNotHavePhomSetImage;
    private Image denLangImage;
    private Image winImage;
    private Image winByUImage;
    private Image loseImage;
    private Image depositOrderImage;
    private Image resultOrderImages;
    private Image cardImages;
    //------------------------------------------------------------------------
//    private boolean[] isBelongOfPairSet;
    private boolean[] isBelongOfFlushSet;
    private boolean[] isNotHavePhom;
//    private int[] phomIdArr;
    private int[][] pairSet;
//    private int[] pairSetIndex;
    private int[] pairIndex;
    private int[][] flushSet;
    private int[] flushIndex;
    private int[][] phomSet;
    private int[] phomCardIndex;
    private int[] phomIndex;
    private boolean[] flushSetChoosed;
    private boolean[] pairSetChoosed;
    //private int[] phomFinal;
    private int[] depositTargerArr;
    private int[] depositNumberArr;
    private int[] cardCheckIdArr;
    private int[] cardFightedIndex;
    private int[] depositPostion;
    private int[] resultOrder;
    private int[] depositCardArr;
    private Card[][] cardRemains;
    private int[] cardRemainIndex;
    //---------------------------------------------------------------------------
    //card
    private Card[] cardEated1;
    private Card[] cardEated2;
    private Card[] cardEated3;
    private Card[] cardEated0;
    private Card[] cardMoves;
    private Card[][] cardFighted;
    private Card[][] cardPhomSet;
    private Card cardCanbeEated;
    private int playerDenLang;

    //--------------------------------------------------------------------------
    public PhomScene(MainCanvas parent) {
        super(parent);
        initValue();
        initObject();
        if (isViewer) {
            initForView();
        } else {
            setCardShare(gameData.cardInHandId);
        }
    }

    private void initForView() {
        cardMoves = new Card[NUMBER_CARD_IN_HANDS];
        cardInHands = new Card[NUMBER_CARD_IN_HANDS];
        cardHeight = cardImages.getHeight();
        cardWidth = cardImages.getWidth() / 53;
        topCardInHandInitValue = canvasHeight - cardHeight + 20;
        topCardInHand = topCardInHandInitValue;
        numberPlayersStart = numberPlayers;
        initCardOnTable();
        isShowJoin = true;
    }

    private void initValue() {
        playerDenLang = -1;
        timeForThink = TIME_FOR_THINK;
        isDrawMarkPhomSet = true;
        playerWinByUId = -1;
        isDepositCard = false;
        maxPlayer = gameData.getMaxPlayer();
        myViewId = gameData.getMyViewId();
        playerId = gameData.getPlayerId();
        firstTurn = gameData.getFirstTurn();
        isViewer = (myViewId < maxPlayer ? false : true);
        if (isViewer) {
            subMenu.setList(new String[]{"Rời bàn", "Loa"});
            playerId = 0;
        }
        numberPlayers = gameData.getNumberPlayers();
        firstHaPhom = gameTurn;
        if (isViewer) {
            playerId = 0;
        }
        isDrawClock = true;
        gameRule = gameData.getGameRule();
        gameData.setGameDisplay(this);
        gameTurn = firstTurn;

    }

    private void initObject() {
        try {
            initImage();
            initArr();
        } catch (IOException ex) {
        }
    }

    private void initArr() {
        cardCheckIdArr = new int[NUMBER_CARD_IN_HANDS];
        isBelongOfFlushSet = new boolean[NUMBER_CARD_IN_HANDS];
        flushSetChoosed = new boolean[NUMBER_CARD_IN_HANDS + 3];
        pairSetChoosed = new boolean[NUMBER_CARD_IN_HANDS + 3];
        depositTargerArr = new int[5];
        depositNumberArr = new int[5];
        isNotHavePhom = new boolean[5];
        phomCardIndex = new int[5];
        cardFightedIndex = new int[5];
        cardFighted = new Card[5][5];
        cardPhomSet = new Card[5][10];
        depositPostion = new int[10];
        depositCardArr = new int[10];
        cardRemainIndex = new int[5];
        cardRemains = new Card[5][10];
        for (int i = 0; i < 5; i++) {
            cardFighted[i] = new Card[5];
            cardPhomSet[i] = new Card[10];
        }
        resultOrder = new int[5];

    }

    private void initImage() throws IOException {
        resultOrderImages = Utils.loadImage("number.png");
        boxCenterTable = Utils.loadImage("o_dem_nguoc.png");
        doNotHavePhomSetImage = Utils.loadImage("chay.png");
        denLangImage = Utils.loadImage("den_lang.png");
        winImage = Utils.loadImage("thang.png");
        winByUImage = Utils.loadImage("u.png");
        loseImage = Utils.loadImage("thua.png");
        depositOrderImage = Utils.loadImage("kygui.png");
        cardImages = Utils.loadImage("card.png");
    }

    private void setCardShare(int[] cardIds) {
        numberCardRemains = cardIds.length;
        Debug.d("number card remain :" + numberCardRemains);
        cardMoves = new Card[NUMBER_CARD_IN_HANDS];
        cardInHands = new Card[NUMBER_CARD_IN_HANDS];
        if (!isViewer) {
            for (int i = 0; i < numberCardRemains; i++) {
                int id = cardIds[i];
                cardInHands[i] = new Card(id, Card.STATE_NORMAL, cardImages);
            }
        }
        if (gameData.bcCardId != -1) {
            cardInHands[numberCardRemains] = new Card(gameData.bcCardId, Card.STATE_NORMAL, cardImages);
            numberCardRemains++;
        }
        isHavePhom = false;
        cardHeight = cardImages.getHeight();
        cardWidth = cardImages.getWidth() / 53;
        topCardInHandInitValue = canvasHeight - cardHeight + 20;
        topCardInHand = topCardInHandInitValue;
        numberPlayersStart = numberPlayers;
        if (Debug.isTest) {
            initForTestEat();
        }
        initCardOnTable();
        if (!isViewer) {
            setCardPosition();
            extractPhom();
        }

    }

    private void initForTestEat() {
        cardCanbeEated = new Card(9, Card.STATE_NORMAL, cardImages);
        cardCanbeEated.setPosition(10, 100);
        cardFightedIndex[3] = 1;
        isHaPhom = true;
//        startSetIndex = 3;
        isGetMoreCard = true;
//        phomFinal[0] = 6;
//        phomFinal[1] = 19;
//        phomFinal[2] = 45;
        cardFighted[3][0] = cardCanbeEated;
        maxPlayer = 4;
        playerFightid = 3;
    }

    public void dispose() {
        boxCenterTable = null;
        doNotHavePhomSetImage = null;
        denLangImage = null;
        winImage = null;
        winByUImage = null;
        loseImage = null;
        depositOrderImage = null;
        resultOrderImages = null;
        cardImages = null;
//        isBelongOfPairSet = null;
        isBelongOfFlushSet = null;
        isNotHavePhom = null;
//        phomIdArr = null;
        //private int[] phomFinal;
        depositTargerArr = null;
        depositNumberArr = null;
        cardCheckIdArr = null;
        phomCardIndex = null;
        cardFightedIndex = null;
        depositPostion = null;
        resultOrder = null;
        depositCardArr = null;
        //card
        cardEated1 = null;
        cardEated2 = null;
        cardEated3 = null;
        cardEated0 = null;
        cardMoves = null;
        cardFighted = null;
        cardPhomSet = null;
        cardCanbeEated = null;
        if (isGoBack) {
            gameData.disposeCardInHand();
        }
        super.dispose();
    }
//------------------------------------------------------------------------------

    private void winbyU() {
        Debug.d("U thang ca lang");

        int phomSendToServerIndex = 0;
        int[] phomSendToServerId = new int[NUMBER_CARD_IN_HANDS];

        for (int i = 0; i < phomIndex[0]; i++) {
            phomSendToServerId[phomSendToServerIndex] = phomSet[0][i];
            phomSendToServerIndex++;
        }

        for (int i = 0; i < phomIndex[1]; i++) {
            phomSendToServerId[phomSendToServerIndex] = phomSet[1][i];
            phomSendToServerIndex++;
        }

        for (int i = 0; i < phomIndex[2]; i++) {
            phomSendToServerId[phomSendToServerIndex] = phomSet[2][i];
            phomSendToServerIndex++;
        }
        handCurseurIndex = 0;
        if (phomSendToServerIndex > 9) {
            phomSendToServerIndex = 9;
        }
        Request.haphom(playerId, phomSendToServerId, phomSendToServerIndex);
        movePhomSet(phomSendToServerId, phomSendToServerIndex, playerId);
        if (numberEats != 3) {
            Request.winUPhom(-1);
        } else {
            Request.winUPhom(playerFightid);
        }


    }

    private int extracPair(int[] cardCheck, int arrLength) {
//        Debug.d("extract pair");
        pairSet = new int[3][4];
        pairIndex = new int[3];
        for (int i = 0; i < 3; i++) {
            pairSet[i] = new int[4];
        }
        // xep theo do giam cua quan bai
        sortCardIncrease(cardCheck, arrLength);
//        printArr2(cardCheck, arrLength);
        int index = 0;
        for (int i = 0; i < arrLength - 2; i++) {
            if (cardCheck[i] % 13 == cardCheck[i + 1] % 13
                    && cardCheck[i + 1] % 13 == cardCheck[i + 2] % 13) {
                int countNumberCard = 0;
                pairSet[index][countNumberCard] = cardCheck[i];
                pairSet[index][countNumberCard + 1] = cardCheck[i + 1];
                pairSet[index][countNumberCard + 2] = cardCheck[i + 2];
                countNumberCard += 3;
                if (i < arrLength - 3) {
                    if (cardCheck[i + 2] % 13 == cardCheck[i + 3] % 13) {
                        pairSet[index][countNumberCard] = cardCheck[i + 3];
                        countNumberCard++;
                    }
                }
                pairIndex[index] = countNumberCard;
                i += countNumberCard - 1;
                index++;
            }
        }
        printArr(pairSet, pairIndex);
        return index;
    }

    private void printArr2(int[] arr, int index) {
        for (int i = 0; i < index; i++) {
            Debug.d("arr :" + arr[i]);
        }
    }

    private void printArr(int[][] arr, int[] arrIndex) {
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < arrIndex[i]; j++) {
                Debug.d("set :" + arr[i][j]);
            }
        }
    }

    private void sortCardDecreaseBySuit(int[] cardIds, int arrLength) {
        for (int i = 0, l = arrLength; i < l - 1; i++) {
            for (int j = i; j < l; j++) {
                if (cardIds[j] < cardIds[i]) {
                    int tg = cardIds[i];
                    cardIds[i] = cardIds[j];
                    cardIds[j] = tg;
                }
            }
        }

    }

    public void sortCardPhom(int[] dataArr, int arrLength) {
//sap theo thu tu tang
        for (int i = 0, l = arrLength; i < l - 1; i++) {
            for (int j = i; j < l; j++) {
                if ((dataArr[i]) % 13 > (dataArr[j]) % 13) {
                    int tg = dataArr[i];
                    dataArr[i] = dataArr[j];
                    dataArr[j] = tg;
                } else if (dataArr[i] % 13 == dataArr[j] % 13) {
                    if (dataArr[i] / 13 > dataArr[j] / 13) {
                        int tg = dataArr[i];
                        dataArr[i] = dataArr[j];
                        dataArr[j] = tg;
                    }
                }
            }
        }

    }

    public void sortCardIncrease(int[] dataArr, int arrLength) {
        for (int i = 0, l = arrLength; i < l - 1; i++) {
            for (int j = i; j < l; j++) {
                if ((dataArr[i]) % 13 > (dataArr[j]) % 13) {
                    int tg = dataArr[i];
                    dataArr[i] = dataArr[j];
                    dataArr[j] = tg;
                } else if (dataArr[i] % 13 == dataArr[j] % 13) {
                    if (dataArr[i] / 13 > dataArr[j] / 13) {
                        int tg = dataArr[i];
                        dataArr[i] = dataArr[j];
                        dataArr[j] = tg;
                    }
                }
            }
        }

    }

    private void sortCardBySet() {
        extractPhom();
        // xep phom
        int startIndex = 0;
        for (int i = 0; i < phomIndex[0]; i++) {
            for (int j = startIndex; j < numberCardRemains; j++) {
                if (cardInHands[j].getCardId() == phomSet[0][i]) {
                    swapCard(startIndex, j);
                    startIndex++;
                }
            }
        }
        for (int i = 0; i < phomIndex[1]; i++) {
            for (int j = startIndex; j < numberCardRemains; j++) {
                if (cardInHands[j].getCardId() == phomSet[1][i]) {
                    swapCard(startIndex, j);
                    startIndex++;
                }
            }
        }
        for (int i = 0; i < phomIndex[2]; i++) {
            for (int j = startIndex; j < numberCardRemains; j++) {
                if (cardInHands[j].getCardId() == phomSet[2][i]) {
                    swapCard(startIndex, j);
                    startIndex++;
                }
            }
        }
        for (int i = startIndex; i < numberCardRemains - 1; i++) {
            for (int j = i; j < numberCardRemains; j++) {
                if (cardInHands[i].getCardId() % 13 < cardInHands[j].getCardId() % 13) {
                    swapCard(i, j);
                } else if (cardInHands[i].getCardId() % 13 == cardInHands[j].getCardId() % 13) {
                    if (cardInHands[i].getCardId() / 13 < cardInHands[j].getCardId() / 13) {
                        swapCard(i, j);
                    }
                }
            }
        }
        markPhomSet();
    }

    private int extractFlush(int[] cardCheck, int arrLength) {
//        Debug.d("extrac flush");
        sortCardDecreaseBySuit(cardCheck, arrLength);
        flushSet = new int[3][5];
        flushIndex = new int[3];
        for (int i = 0; i < 3; i++) {
            flushSet[i] = new int[5];
        }
//        printArr2(cardCheck, arrLength);
        int index = 0;
        for (int i = 0; i < arrLength - 2; i++) {
            if (cardCheck[i] == cardCheck[i + 1] - 1
                    && cardCheck[i + 1] == cardCheck[i + 2] - 1
                    && cardCheck[i] / 13 == cardCheck[i + 1] / 13
                    && cardCheck[i] / 13 == cardCheck[i + 2] / 13) {
                flushSet[index][0] = cardCheck[i];
                flushSet[index][1] = cardCheck[i + 1];
                flushSet[index][2] = cardCheck[i + 2];
                int countNumberCard = 3;

                if (i < arrLength - 3) {
                    if (cardCheck[i + 2] == cardCheck[i + 3] - 1
                            && cardCheck[i] / 13 == cardCheck[i + 3] / 13) {
                        flushSet[index][countNumberCard] = cardCheck[i + 3];
                        countNumberCard++;
                    }
                }
                if (i < arrLength - 4 && countNumberCard == 4) {
                    if (cardCheck[i + 3] == cardCheck[i + 4] - 1
                            && cardCheck[i] / 13 == cardCheck[i + 4] / 13) {
                        flushSet[index][countNumberCard] = cardCheck[i + 4];
                        countNumberCard++;
                    }
                }
                if (i < arrLength - 5 && countNumberCard == 5) {
                    if (cardCheck[i + 4] == cardCheck[i + 5] - 1
                            && cardCheck[i] / 13 == cardCheck[i + 5] / 13) {
                        countNumberCard = 3;
                    }
                }
                flushIndex[index] = countNumberCard;
                i += countNumberCard - 1;
                index++;
                // Debug.d("next i :" + i);
            }
        }
        printArr(flushSet, flushIndex);
        return index;
    }

    private int getPoint(int cardId) {
        return cardId % 13 + 1;
    }

    private void markChooseFlush(int startFlush, int offSet, boolean isChoosed) {
//        Debug.d("choose flush:" + isChoosed);
        for (int i = startFlush; i < startFlush + offSet; i++) {
            flushSetChoosed[i] = isChoosed;
        }
    }

//    private void chooseFlush(int[] flush, int startFlush, int offSet) {
//        Debug.d("choose flush:");
//        for (int i = startFlush; i < startFlush + offSet; i++) {
//            if (flush[i] != -1) {
//                flushSetChoosed[i] = true;
//                phomIdArr[phomIdArrIndex] = flush[i];
//                phomIdArrIndex++;
//            }
//        }
//    }
    private void markChoosePair(int startPair, int offSet, boolean isChoosed) {
        Debug.d("choose pair:" + isChoosed);
        for (int i = startPair; i < startPair + offSet; i++) {
            pairSetChoosed[i] = isChoosed;
        }
    }

    private boolean checkAutoEatCard(int cardCheckEat) {
        int checkIndex = 0;
        int[] pair = new int[4];
        int[] flush = new int[NUMBER_CARD_IN_HANDS];
        int pairLength = 0;
        int flushLength = 0;
        for (int i = 0; i < numberCardRemains; i++) {
            Card card = cardInHands[i];
            if (!card.isCardEated) {
                cardCheckIdArr[checkIndex] = cardInHands[i].getCardId();
                checkIndex++;
            }
        }

        pairLength = findPair(cardCheckIdArr, checkIndex, cardCheckEat, pair);
        flushLength = findFlush(cardCheckIdArr, checkIndex, cardCheckEat, flush);
        Debug.d("check pair :" + pairLength);
        Debug.d("check flush :" + flushLength);
        if (pairLength < 3 && flushLength < 3) {
            return false;
        }

        if (pairLength >= 3 && flushLength < 3) {
            cardCheckIdArr[0] = pair[0];
            cardCheckIdArr[1] = pair[1];
            cardCheckIdArr[2] = pair[2];
            return true;
        }

        if (flushLength >= 3 && pairLength < 3) {
            Debug.d("check :" + cardCheckEat);
            Debug.d("2:" + flush[0]);
            cardCheckIdArr[0] = flush[0];
            cardCheckIdArr[1] = flush[1];
            cardCheckIdArr[2] = flush[2];
            return true;
        }
        if (flushLength >= 3 && pairLength >= 3) {
            if (sumPhomPoint(pair, pairLength) < sumPhomPoint(flush, flushLength)) {
                cardCheckIdArr[0] = flush[0];
                cardCheckIdArr[1] = flush[1];
                cardCheckIdArr[2] = flush[2];
                return true;
            }
            cardCheckIdArr[0] = pair[0];
            cardCheckIdArr[1] = pair[1];
            cardCheckIdArr[2] = pair[2];
            return true;
        }
        return false;
    }

    private void sortIncreaseBySuit(int[] cardIds, int length) {
        for (int i = 0; i < length - 1; i++) {
            for (int j = i + 1; j < length; j++) {
                if (cardIds[i] / 13 > cardIds[j] / 13) {
                    int tg = cardIds[i];
                    cardIds[i] = cardIds[j];
                    cardIds[j] = tg;
                } else if (cardIds[i] / 13 == cardIds[j] / 13) {
                    if (cardIds[i] % 13 > cardIds[j] % 13) {
                        int tg = cardIds[i];
                        cardIds[i] = cardIds[j];
                        cardIds[j] = tg;
                    }
                }
            }
        }
    }

    private int findFlush(int[] cardIds, int length, int cardCheckEat, int[] resultId) {

        Debug.d("find flush ");
//        printArr2(cardIds, length);
        sortIncreaseBySuit(cardIds, length);
        for (int i = 0; i < length; i++) {
            if (i > 0) {
                if (cardCheckEat == cardIds[i] + 1
                        && cardCheckEat == cardIds[i - 1] + 2
                        && cardCheckEat / 13 == cardIds[i] / 13
                        && cardCheckEat / 13 == cardIds[i - 1] / 13) {
                    resultId[0] = cardIds[i - 1];
                    resultId[1] = cardIds[i];
                    resultId[2] = cardCheckEat;
                    return 3;
                }
            }
            if (i < length - 1) {
                if (cardCheckEat == cardIds[i] - 1
                        && cardCheckEat == cardIds[i + 1] - 2
                        && cardCheckEat / 13 == cardIds[i] / 13
                        && cardCheckEat / 13 == cardIds[i + 1] / 13) {

                    resultId[0] = cardCheckEat;
                    resultId[1] = cardIds[i];
                    resultId[2] = cardIds[i + 1];
                    return 3;
                }
            }
            if (i > 0) {
                if (cardCheckEat == cardIds[i] - 1
                        && cardCheckEat == cardIds[i - 1] + 1
                        && cardCheckEat / 13 == cardIds[i] / 13
                        && cardCheckEat / 13 == cardIds[i - 1] / 13) {
                    resultId[0] = cardIds[i - 1];
                    resultId[1] = cardCheckEat;
                    resultId[2] = cardIds[i];
                    return 3;
                }
            }

        }
        return 0;

    }

    private int findPair(int[] cardIds, int length, int cardCheckEat, int[] resultId) {
        int count = 0;
        for (int i = 0; i < length; i++) {
            if (cardCheckEat % 13 == cardIds[i] % 13) {
                resultId[count] = cardIds[i];
                count++;
            }
        }
        resultId[count] = cardCheckEat;
        count++;
        sortCardIncrease(cardIds, length);
        return count;
    }

    private void extractPhom() {
        Debug.d("extract phom ");
        phomSet = new int[3][5];
        phomIndex = new int[3];
        int checkIndex = 0;
        int startId = 0;
        for (int i = 0; i < numberCardRemains; i++) {
            Card card = cardInHands[i];
            if (card.isCardEated) {
                phomSet[card.eatId][card.phomId] = card.getCardId();
                phomIndex[card.eatId] = (phomIndex[card.eatId] > card.phomId + 1 ? phomIndex[card.eatId] : card.phomId + 1);
                startId = (card.eatId + 1 > startId ? card.eatId + 1 : startId);
            } else {
                cardCheckIdArr[checkIndex] = cardInHands[i].getCardId();
                checkIndex++;
            }
        }
        int saveId = startId;

        numberPairs = extracPair(cardCheckIdArr, checkIndex);
        numberFlushs = extractFlush(cardCheckIdArr, checkIndex);
        //ko co phom nao
        if (numberFlushs > 0 && numberPairs == 0) {
            int index = 0;
            do {
                if (flushIndex[index] > 0) {
                    phomSet[startId] = flushSet[index];
                    phomIndex[startId] = flushIndex[index];
                    startId++;
                }
                index++;
            } while (index < 3);
        }


        if (numberPairs > 0 && numberFlushs == 0) {
            int index = 0;
            do {
                if (pairIndex[index] > 0) {
                    phomSet[startId] = pairSet[index];
                    phomIndex[startId] = pairIndex[index];
                    startId++;
                }
                index++;
            } while (index < 3);
        }

        if (numberFlushs > 0 && numberPairs > 0) {
            startId = choosePhom(startId);
        }
        if (saveId > 0) {
            markPhom();
            int[] cardNotPhom = new int[NUMBER_CARDS];
            int index = 0;
            for (int i = 0; i < numberCardRemains; i++) {
                if (!isBelongOfFlushSet[i]) {
                    cardNotPhom[index] = cardInHands[i].getCardId();
                    index++;
                }
            }
            addToPhom(cardNotPhom, index, saveId);
        }
        numberPhoms = markPhomSet();;
        Debug.d("number phom:" + numberPhoms);
        printArr(phomSet, phomIndex);
        if (numberPhoms >= 9) {
            winbyU();
        }
    }

    private void addToPhom(int[] cardIds, int index, int saveId) {
        Debug.d("add phom");
//        printArr2(cardIds, index);
//        Debug.d("card check");
//        printArr2(cardCheckIdArr, 3);
        int phomId = 0;
        int typeSet = 0;
        boolean isAdded = false;
        do {
            int[] set = phomSet[phomId];
            int setIndex = phomIndex[phomId];
            if (set[0] % 13 == set[1] % 13) {
                typeSet = PAIR_SET;
                sortCardIncrease(cardIds, index);
                if (setIndex == 4) {
                    return;
                }
            } else {
                typeSet = FLUSH_SET;
                sortIncreaseBySuit(cardIds, index);
                if (setIndex == 5) {
                    return;
                }
            }
            Debug.d("type set :" + typeSet);
            if (typeSet == PAIR_SET) {
                for (int i = 0; i < index; i++) {
                    int cardId = cardIds[i];
                    if (cardId % 13 == set[0] % 13) {
                        Debug.d("card id :" + cardId);
                        Debug.d("card check id:" + cardCheckIdArr[0]);
                        phomSet[phomId][setIndex] = cardId;
                        phomIndex[phomId] = setIndex + 1;
//                        isAdded = true;
                        break;
                    }
                }
            }
            if (typeSet == FLUSH_SET) {
                int maxId = set[setIndex - 1];
                int minId = set[0];
                // sort
                for (int i = 0; i < index; i++) {
                    int cardId = cardIds[i];
                    if (cardId / 13 == minId / 13) {
                        if (cardId == minId - 2 && i < index - 1) {
                            if (cardIds[i + 1] == minId - 1) {
                                setIndex++;
                                for (int k = setIndex - 1; k >= 1; k--) {
                                    phomSet[phomId][k] = phomSet[phomId][k - 1];
                                }
                                phomSet[phomId][0] = cardId;
                                phomIndex[phomId] = setIndex;
                            }
                        }
                        if (cardId == minId - 1) {
                            setIndex++;
                            for (int k = setIndex - 1; k >= 1; k--) {
                                phomSet[phomId][k] = phomSet[phomId][k - 1];
                            }
                            phomSet[phomId][0] = cardId;
                            phomIndex[phomId] = setIndex;
                        }
                        if (cardId == maxId + 1) {
                            phomSet[phomId][setIndex] = cardId;
                            setIndex++;
                            phomIndex[phomId] = setIndex;
                        }
                        if (cardId == maxId + 2 && i > 0) {
                            if (cardIds[i - 1] == maxId + 1) {
                                phomSet[phomId][setIndex] = cardId;
                                setIndex++;
                                phomIndex[phomId] = setIndex;
                            }
                        }
                    }
                }
            }
            phomId++;
        } while (phomId < saveId);
//        Debug.d("is added :" + isAdded);
//        if (isAdded) {
//            extractPhom();
//        }
    }

    private int findRemainCard(int startSetIndex) {
        Debug.d("find card remain");
        int cardChooseIndex = 3;
        if (eatSetType == PAIR_SET) {
            for (int i = startSetIndex; i < numberCardRemains; i++) {
                int cardId = cardInHands[i].getCardId();
                if (cardId % 13 == cardCheckIdArr[0] % 13
                        && cardId != cardCheckIdArr[0]
                        && cardId != cardCheckIdArr[1]
                        && cardId != cardCheckIdArr[2]) {
                    cardCheckIdArr[cardChooseIndex] = cardId;
                    cardChooseIndex++;
                    if (Debug.isTest) {
                        for (int j = 0; j < cardChooseIndex; j++) {
                            Debug.d("card eat set:" + cardCheckIdArr[i]);
                        }
                    }
                    return cardChooseIndex;
                }
            }
        }
        if (eatSetType == FLUSH_SET) {
            int maxId = cardCheckIdArr[2];
            int minId = cardCheckIdArr[0];
            // sort
            for (int i = startSetIndex; i < numberCardRemains - 1; i++) {
                for (int j = startSetIndex + 1; j < numberCardRemains; j++) {
                    if (cardInHands[i].getCardId() % 13 > cardInHands[j].getCardId() % 13) {
                        swapCard(i, j);
                    } else if (cardInHands[i].getCardId() % 13 == cardInHands[j].getCardId() % 13) {
                        if (cardInHands[i].getCardId() / 13 > cardInHands[j].getCardId() / 13) {
                            swapCard(i, j);
                        }
                    }
                }
            }
            for (int i = startSetIndex; i < numberCardRemains; i++) {
                int cardId = cardInHands[i].getCardId();
//                Debug.d("max id :" + maxId);
//                Debug.d("min id :" + minId);
//                Debug.d("card id :" + cardId);
//                Debug.d("------------------------------");

                if (cardId == minId - 1) {
                    minId = cardId;
                    cardCheckIdArr[cardChooseIndex] = minId;
                    cardChooseIndex++;
                }
                if (cardId == maxId + 1) {
                    maxId = cardId;
                    cardCheckIdArr[cardChooseIndex] = maxId;
                    cardChooseIndex++;
                }
            }
            sortCardPhom(cardCheckIdArr, cardChooseIndex);
            if (Debug.isTest) {
                for (int i = 0; i < cardChooseIndex; i++) {
                    Debug.d("card eat set:" + cardCheckIdArr[i]);
                }
            }

            return cardChooseIndex;

        }
        if (Debug.isTest) {
            for (int i = 0; i < cardChooseIndex; i++) {
                Debug.d("card eat set:" + cardCheckIdArr[i]);
            }
        }
        return cardChooseIndex;

    }

    private int markPhom() {
        int numberCardInPhom = 0;
        for (int i = 0; i < numberCardRemains; i++) {
            isBelongOfFlushSet[i] = false;
        }

        for (int i = 0; i < phomIndex[0]; i++) {
            for (int j = 0; j < numberCardRemains; j++) {
                if (phomSet[0][i] == cardInHands[j].getCardId()) {
                    isBelongOfFlushSet[j] = true;
                    numberCardInPhom++;
                }
            }
        }
        for (int i = 0; i < phomIndex[1]; i++) {
            for (int j = 0; j < numberCardRemains; j++) {
                if (phomSet[1][i] == cardInHands[j].getCardId()) {
                    isBelongOfFlushSet[j] = true;
                    numberCardInPhom++;
                }
            }
        }
        for (int i = 0; i < phomIndex[2]; i++) {
            for (int j = 0; j < numberCardRemains; j++) {
                if (phomSet[2][i] == cardInHands[j].getCardId()) {
                    isBelongOfFlushSet[j] = true;
                    numberCardInPhom++;
                }
            }
        }
        return numberCardInPhom;
    }

    private int choosePhom(int startId) {
        boolean[] chooseType = new boolean[4];
        if (numberFlushs == 1 && numberPairs == 1) {
            if (isRepeat(0, 0)) {
                switch (chooseSet(0, 0)) {
                    case CHOOSE_FLUSH:
                        chooseType[2] = true;
                        break;
                    case CHOOSE_PAIR:
                        chooseType[0] = true;
                        break;
                    case CHOOSE_ALL:
                        chooseType[0] = true;
                        chooseType[2] = true;
                        break;
                }
            } else {
                chooseType[0] = true;
                chooseType[2] = true;
            }
        }
        if (numberPairs == 1 && numberFlushs == 2) {
            int repeatType = 0;
            if (isRepeat(0, 0)) {
                repeatType += 2;
            }
            if (isRepeat(0, 1)) {
                repeatType += 4;
            }
            if (repeatType == 6) {
                chooseType[3] = true;
                chooseType[2] = true;
            }
            if (repeatType == 0) {
                chooseType[3] = true;
                chooseType[2] = true;
                chooseType[0] = true;
            }
            if (repeatType == 2) {
                chooseType[3] = true;
                switch (chooseSet(0, 0)) {
                    case CHOOSE_FLUSH:
                        chooseType[2] = true;
                        break;
                    case CHOOSE_PAIR:
                        chooseType[0] = true;
                        break;
                    case CHOOSE_ALL:
                        chooseType[0] = true;
                        chooseType[2] = true;
                        break;
                }
            }
            if (repeatType == 4) {
                chooseType[2] = true;
                switch (chooseSet(0, 1)) {
                    case CHOOSE_FLUSH:
                        chooseType[3] = true;
                        break;
                    case CHOOSE_PAIR:
                        chooseType[0] = true;
                        break;
                    case CHOOSE_ALL:
                        chooseType[0] = true;
                        chooseType[3] = true;
                        break;
                }
            }


        }
        if (numberPairs == 2 && numberFlushs == 1) {
            int repeatType = 0;
            if (isRepeat(0, 0)) {
                repeatType += 2;
            }
            if (isRepeat(1, 0)) {
                repeatType += 4;
            }
            if (repeatType == 6) {
                chooseType[0] = true;
                chooseType[1] = true;
            }
            if (repeatType == 0) {
                chooseType[0] = true;
                chooseType[1] = true;
                chooseType[2] = true;
            }
            if (repeatType == 2) {
                chooseType[1] = true;
                switch (chooseSet(0, 0)) {
                    case CHOOSE_FLUSH:
                        chooseType[2] = true;
                        break;
                    case CHOOSE_PAIR:
                        chooseType[0] = true;
                        break;
                    case CHOOSE_ALL:
                        chooseType[0] = true;
                        chooseType[2] = true;
                        break;
                }
            }
            if (repeatType == 4) {
                chooseType[0] = true;
                switch (chooseSet(1, 0)) {
                    case CHOOSE_FLUSH:
                        chooseType[2] = true;
                        break;
                    case CHOOSE_PAIR:
                        chooseType[1] = true;
                        break;
                    case CHOOSE_ALL:
                        chooseType[1] = true;
                        chooseType[3] = true;
                        break;
                }
            }

        }
        int phomId = startId;
        int index = 0;
        if (chooseType[0]) {
//            Debug.d("choose 0");
            for (int i = 0; i < pairIndex[0]; i++) {
                if (pairSet[0][i] != -1) {
                    phomSet[phomId][index] = pairSet[0][i];
                    index++;
                    phomIndex[phomId] = index;
                }
            }
            phomId++;

        }
        if (chooseType[1]) {
            index = 0;
//            Debug.d("choose 1");
            for (int i = 0; i < pairIndex[1]; i++) {
                if (pairSet[1][i] != -1) {
                    phomSet[phomId][index] = pairSet[1][i];
                    index++;
                    phomIndex[phomId] = index;
                }
            }
            phomId++;

        }
        if (chooseType[2]) {
            index = 0;
//            Debug.d("choose 2");
            for (int i = 0; i < flushIndex[0]; i++) {
                if (flushSet[0][i] != -1) {
                    phomSet[phomId][index] = flushSet[0][i];
                    index++;
                    phomIndex[phomId] = index;
                }
            }
            phomId++;

        }
        if (chooseType[3]) {
            index = 0;
//            Debug.d("choose 3");
            for (int i = 0; i < flushIndex[1]; i++) {
                if (flushSet[1][i] != -1) {
                    phomSet[phomId][index] = flushSet[1][i];
                    index++;
                    phomIndex[phomId] = index;
                }
            }
            phomId++;

        }
        return (phomId + startId);

    }

    private int sumPhomPoint(int[] arr, int index) {
        int sum = 0;
        for (int i = 0; i < index; i++) {
            sum += getPoint(arr[i]);
        }
//        Debug.d("sum :"+sum);
        return sum;
    }

    private int chooseSet(int pId, int fId) {
        int pIndex = pairIndex[pId];
        int fIndex = flushIndex[fId];
        if (pIndex == 3 && fIndex == 3) {
            if (sumPhomPoint(pairSet[pId], pIndex) > sumPhomPoint(flushSet[fId], fIndex)) {
                return CHOOSE_PAIR;
            } else {
                return CHOOSE_FLUSH;
            }
        }
        if (pIndex == 3 && fIndex > 3) {
            if (flushSet[fId][0] % 13 == pairSet[pId][0] % 13) {
                flushSet[fId][0] = -1;
                return CHOOSE_ALL;
            }
            if (flushSet[fId][fIndex - 1] % 13 == pairSet[pId][0] % 13) {
                flushSet[fId][fIndex - 1] = -1;
                return CHOOSE_ALL;
            }

            if (sumPhomPoint(pairSet[pId], pIndex) > sumPhomPoint(flushSet[fId], fIndex)) {
                return CHOOSE_PAIR;
            } else {
                return CHOOSE_FLUSH;
            }
        }
        if (pIndex == 4) {
            for (int i = 0; i < pIndex; i++) {
                if (pairSet[pId][i] / 13 == flushSet[fId][0] / 13) {
                    pairSet[pId][i] = -1;
                    return CHOOSE_ALL;
                }
            }
        }

        return CHOOSE_ALL;
    }

    private boolean isRepeat(int pIndex, int fIndex) {
        for (int i = 0; i < pairIndex[pIndex]; i++) {
            for (int j = 0; j < flushIndex[fIndex]; j++) {
                if (pairSet[pIndex][i] == flushSet[fIndex][j]) {
                    return true;
                }
            }
        }
        return false;
    }

    private void mergePhom(int[] phomSetPair, int setPairLength, int[] phomSetFlush, int flushLength) {
//        int pairIndex;
//        int flushIndex;
//        int sumPair;
//        int sumFlush;
//        int startFlushIndex = 0;
//        int startPairIndex = 0;
//        do {
//            pairIndex = 0;
//            flushIndex = 0;
//            sumPair = 0;
//            sumFlush = 0;
//            //chon pair
//            for (int i = startPairIndex; i < setPairLength; i++) {
//                if (phomSetPair[i] != -1) {
//                    if (pairSetChoosed[i]) {
//                        pairSet[pairIndex] = phomSetPair[i];
//                        sumPair += getPoint(pairSet[pairIndex]);
//                        pairIndex++;
//                    }
//                    continue;
//                }
//                if (pairSetChoosed[i - 1]) {
//                    break;
//                }
//            }
//
//            //chon flush
//            for (int i = startFlushIndex; i < flushLength; i++) {
//                if (phomSetFlush[i] != -1) {
//                    if (flushSetChoosed[i]) {
//                        flushSet[flushIndex] = phomSetFlush[i];
//                        sumFlush += getPoint(flushSet[flushIndex]);
//                        flushIndex++;
//                    }
//                    continue;
//                }
//                if (flushSetChoosed[i - 1]) {
//                    break;
//                }
//            }
//            Debug.d(" start pair  index:" + startPairIndex);
//            Debug.d(" start flush index :" + startFlushIndex);
//            if (checkRepeat(pairIndex, flushIndex) != -1) {
//                if (pairIndex == 3 && flushIndex == 3) {
//                    mergeSet33(startPairIndex, pairIndex, sumPair, startFlushIndex, flushIndex, sumFlush);
//                } else if (pairIndex == 3 && flushIndex == 4) {
//                    mergeSet34(pairIndex, sumPair, sumFlush, flushIndex);
//                } else if (pairIndex == 3 && flushIndex == 5) {
//                    mergeSet35(pairIndex, sumPair, sumFlush, flushIndex);
//                } else if (pairIndex == 4 && flushIndex == 4) {
//                    mergeSet44(pairIndex, sumPair, sumFlush, flushIndex);
//                } else if (pairIndex == 4 && flushIndex == 5) {
//                    mergeSet45(pairIndex, sumPair, sumFlush, flushIndex);
//                }
////                startFlushIndex = flushLength
//            }
//            startFlushIndex += flushIndex + 1;
//
//            if (startFlushIndex >= flushLength) {
//                startPairIndex += pairIndex + 1;
//                startFlushIndex = 0;
//            }
//        } while (startPairIndex < setPairLength - 1);
//
//
//
    }

    private int mergeSet33(int startPair, int pairIndex, int sumPair, int startFlush, int flushIndex, int sumFlush) {
        Debug.d("truong hop 3:3");
        //co lap chon 1 trong 2
        if (sumFlush > sumPair) {
//            chooseFlush(flushSet, startFlush, flushIndex);
//            markChooseFlush(startFlush, flushIndex, true);
            markChoosePair(startPair, pairIndex, false);
            return CHOOSE_FLUSH;
        } else {
            markChooseFlush(startFlush, flushIndex, false);
//            markChoosePair(startPair, pairIndex, false);
            return CHOOSE_PAIR;
        }
    }

    private void initCardOnTable() {
        cardEated1 = new Card[3];
        cardEated2 = new Card[3];
        cardEated3 = new Card[3];
        cardEated0 = new Card[3];
    }

    //-------------------------------------------------------------------------
    protected void paintCardGame(Graphics g) {
        paintClock(g);
        paintCard(g);
        if (cardMoveIndex > 0) {
            paintCardMove(g);
        }
        paintPlayer(g);
        if (isDepositCard) {
            paintTargerDeposit(g);
        }
        paintBarMenu(g);
//        if (speakFlyString != null) {
//            if (speakFlyString.isShow) {
//                speakFlyString.paint(g);
//            }
//        }
//        if (isShowSpeaker) {
//            speakerBox.paint(g, leftScreen + 10, canvasHeight - 45, canvasWidth - 20, 20);
//        }
    }

    protected void paintBarMenu(Graphics g) {

        if (isShowChatBox || isShowSpeaker) {
            PiPoDesigner.drawString(g, "Đóng", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, leftScreen + 5, canvasHeight - 20);
            PiPoDesigner.drawString(g, "Xóa", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, canvasWidth - 30, canvasHeight - 20);
            PiPoDesigner.drawString(g, "Gửi", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, canvasWidth / 2 - 20, canvasHeight - 20);
            return;
        } else {
            if (!isDepositCard) {
                PiPoDesigner.drawString(g, "Menu", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, leftScreen + 5, canvasHeight - 20);
            } else {
                PiPoDesigner.drawString(g, "Đổi ng.gửi", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, leftScreen + 5, canvasHeight - 20);
                PiPoDesigner.drawString(g, "Gửi", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, canvasWidth / 2 - 15, canvasHeight - 20);
                PiPoDesigner.drawString(g, "Bỏ qua", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, canvasWidth - 40, canvasHeight - 20);
            }
            if (isShowSubMenu) {
                PiPoDesigner.drawString(g, "Đóng", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, canvasWidth - 30, canvasHeight - 20);
                return;
            }
        }
        if (isViewer) {
            if (!isJoinedGame && isShowJoin) {
                PiPoDesigner.drawString(g, "Tham gia", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, canvasWidth / 2 - 30, canvasHeight - 20);
            }
//            if (isFinishGame && isJoinedGame) {
//                PiPoDesigner.drawString(g, "Tiếp tục", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, canvasWidth / 2 - 20, canvasHeight - 20);
//            }
        } else {
            if (!isFinishGame) {
                if (gameTurn == playerId) {
                    if (isGetMoreCard) {
                        PiPoDesigner.drawString(g, "Bốc", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, canvasWidth - 25, canvasHeight - 20);
                        PiPoDesigner.drawString(g, "Ăn", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, canvasWidth / 2 - 15, canvasHeight - 20);
                    } else if (isHaPhom) {
                        PiPoDesigner.drawString(g, "Hạ phỏm", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, canvasWidth / 2 - 25, canvasHeight - 20);
                    } else {
                        if (!isDepositCard) {
                            PiPoDesigner.drawString(g, "Đánh bài", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, canvasWidth / 2 - 30, canvasHeight - 20);
                        }
                    }
                }
            } else {
                PiPoDesigner.drawString(g, "Tiếp tục", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, canvasWidth / 2 - 20, canvasHeight - 20);
            }
        }

    }

    private void paintTargerDeposit(Graphics g) {
        Utils.drawFrame(g, depositOrderImage, canvasWidth - 50, canvasHeight - 70, depositTargerArr[depositTargerIndex - 1], 0, depositOrderImage.getWidth() / 4, depositOrderImage.getHeight());
    }

    private void paintPlayer(Graphics g) {
        for (int i = 0; i < maxPlayer; i++) {
            if (gameData.isPlays[i]) {
                paintPlayerInfo(g, i);
            }
        }
    }

    private void paintPlayerInfo(Graphics g, int id) {
        int posId = (id - playerId + maxPlayer) % maxPlayer;
        switch (posId) {
            case 0:
                if (isViewer) {
                    //draw result
                    if (gameTurn == id && isShowPlayerName || gameTurn != id) {
                        PiPoDesigner.drawString(g, gameData.playerName[id], PiPoDesigner.COLOR_BLACK,
                                PiPoDesigner.COLOR_WHITE, positionX[posId], positionY[posId] - 10);
                    }
                    Utils.drawFrame(g, avatarImage, positionX[posId], positionY[posId], gameData.avatarIds[id], gameData.playerGender[id], avatarWidth, avatarHeight);
                    paintResultPhom(g, id, positionX[posId], positionY[posId] - 30);
                } else {
                    if (isDrawResult) {
                        //draw result
                        PiPoDesigner.drawString(g, gameData.playerName[id], PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, positionX[posId], positionY[posId] - 10);
                        Utils.drawFrame(g, avatarImage, positionX[posId], positionY[posId], gameData.avatarIds[id], gameData.playerGender[id], avatarWidth, avatarHeight);
                        paintResultPhom(g, id, positionX[posId], positionY[posId] - 30);
                    }
                }
                break;
            case 1:
                //name
                if (gameTurn == id && isShowPlayerName) {
                    PiPoDesigner.drawString(g, gameData.playerName[id], PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, positionX[posId], positionY[posId] - 90);
                } else if (gameTurn != id) {
                    PiPoDesigner.drawString(g, gameData.playerName[id], PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, positionX[posId], positionY[posId] - 90);
                }
                //avatar
                Utils.drawFrame(g, avatarImage, positionX[posId], positionY[posId] - 80, gameData.avatarIds[id], gameData.playerGender[id], avatarWidth, avatarHeight);
                paintResultPhom(g, id, positionX[posId] - 40, positionY[posId] - 60);
                paintDepositOrder(g, id);
                break;
            case 2:
                //name
                if ((gameTurn == id && isShowPlayerName)) {
                    PiPoDesigner.drawString(g, gameData.playerName[id], PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, positionX[posId] - 60, positionY[posId] - 10);
                } else if (gameTurn != id) {
                    PiPoDesigner.drawString(g, gameData.playerName[id], PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, positionX[posId] - 60, positionY[posId] - 10);
                }
                //avatar
                Utils.drawFrame(g, avatarImage, positionX[posId] - 60, positionY[posId], gameData.avatarIds[id], gameData.playerGender[id], avatarWidth, avatarHeight);
                paintResultPhom(g, id, positionX[posId] - 40, positionY[posId] + 20);
                paintDepositOrder(g, id);
                break;
            case 3:
                //name
                int nameWidth = PiPoDesigner.stringWidth(gameData.playerName[id]);
                if (nameWidth < 50) {
                    if ((gameTurn == id && isShowPlayerName)) {
                        PiPoDesigner.drawString(g, gameData.playerName[id], PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, positionX[posId] - 10, positionY[posId] + 40);
                    } else if (gameTurn != id) {
                        PiPoDesigner.drawString(g, gameData.playerName[id], PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, positionX[posId] - 10, positionY[posId] + 40);
                    }
                } else {
                    g.setClip(positionX[posId] - 10, positionY[posId] + 40, 50, 30);
                    if ((gameTurn == id && isShowPlayerName)) {
                        PiPoDesigner.drawString(g, gameData.playerName[id], PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, positionX[posId] - 10, positionY[posId] + 40);
                    } else if (gameTurn != id) {
                        PiPoDesigner.drawString(g, gameData.playerName[id], PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, positionX[posId] - 10, positionY[posId] + 40);
                    }

                    g.setClip(0, 0, canvasWidth, canvasHeight);
                    if ((gameTurn == id && isShowPlayerName)) {
                        PiPoDesigner.drawString(g, "...", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, positionX[posId] + 40, positionY[posId] + 40);
                    } else if (gameTurn != id) {
                        PiPoDesigner.drawString(g, "...", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, positionX[posId] + 40, positionY[posId] + 40);
                    }

                }
                //avatar
                Utils.drawFrame(g, avatarImage, positionX[posId], positionY[posId] + 50, gameData.avatarIds[id], gameData.playerGender[id], avatarWidth, avatarHeight);
                paintResultPhom(g, id, positionX[posId], positionY[posId]);
                paintDepositOrder(g, id);
                break;
        }
    }

    private void paintDepositOrder(Graphics g, int id) {

        if (!isDepositCard || isViewer) {
            return;
        }
        int posId = (id - playerId + maxPlayer) % maxPlayer;
        if (phomCardIndex[posId] > 0) {
            Utils.drawFrame(g, depositOrderImage, positionX[posId], positionY[posId], id, 0, depositOrderImage.getWidth() / 4, depositOrderImage.getHeight());
        }
    }

    private void paintResultPhom(Graphics g, int id, int x, int y) {
        if (!isDrawResult) {
            return;
        }
        if (playerWinByUId != -1) {
            if (id == playerWinByUId) {
                g.drawImage(winByUImage, x, y, 0);
            } else {
                if (id == playerDenLang) {
                    g.drawImage(denLangImage, x, y, 0);
                } else {
                    g.drawImage(loseImage, x, y, 0);
                }
            }
            return;
        }



        //int posId = ((id - playerId + NUMBER_PLAYERS) % NUMBER_PLAYERS);
        switch (resultOrder[id]) {
            case 0:
                g.drawImage(winImage, x, y, 0);
                return;
            case 1:
                g.drawImage(loseImage, x, y, 0);
                //     g.drawImage(resultOraderImages[resultOrder[id]], x + 30, y, 0);
                Utils.drawFrame(g, resultOrderImages, x + 40, y - 5, resultOrder[id] - 1, 0,
                        resultOrderImages.getWidth() / 4, resultOrderImages.getHeight());
                return;
            case 2:
                g.drawImage(loseImage, x, y, 0);
                Utils.drawFrame(g, resultOrderImages, x + 40, y - 5, resultOrder[id] - 1, 0,
                        resultOrderImages.getWidth() / 4, resultOrderImages.getHeight());
                return;
            case 3:
                g.drawImage(loseImage, x, y, 0);
                Utils.drawFrame(g, resultOrderImages, x + 40, y - 5, resultOrder[id] - 1, 0,
                        resultOrderImages.getWidth() / 4, resultOrderImages.getHeight());
                return;
            case 4:
                g.drawImage(doNotHavePhomSetImage, x, y, 0);
                return;
        }
    }

    private void paintCardMove(Graphics g) {
        for (int i = 0; i < cardMoveIndex; i++) {
            cardMoves[i].paint(g);
        }
    }

    private void paintClock(Graphics g) {
        if (isDrawClock) {
            g.drawImage(boxCenterTable, canvasWidth / 2 - boxCenterTable.getWidth() / 2, canvasHeight / 2 - boxCenterTable.getHeight() / 2, 0);
            PiPoDesigner.drawCenterString(g, String.valueOf(timeForThink), PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, canvasWidth / 2, canvasHeight / 2 - 8);
        } else {
            PiPoDesigner.drawCenterString(g, "Xin chờ...", PiPoDesigner.COLOR_BLACK, PiPoDesigner.COLOR_WHITE, canvasWidth / 2, canvasHeight / 2 - 8);
        }
    }

    private void paintCard(Graphics g) {
        //bai da danh
        for (int i = 0; i < 10; i++) {
            if (i < cardFightedIndex[0]) {
                cardFighted[0][i].paint(g);
            }
            if (i < cardRemainIndex[0]) {
                cardRemains[0][i].paint(g);
            }
            //2
            if (i < phomCardIndex[2]) {
                cardPhomSet[2][i].paint(g);
            }
            //3
            if (i < phomCardIndex[3]) {
                cardPhomSet[3][i].paint(g);
            }

        }
        //
        for (int i = 0; i < 10; i++) {
            if (i < cardEatedIndex1) {
                cardEated1[i].paint(g);
            }

            if (i < cardEatedIndex0) {
                cardEated0[i].paint(g);
            }

            if (i < cardRemainIndex[2]) {
                cardRemains[2][i].paint(g);
            }

            if (i < cardRemainIndex[3]) {
                cardRemains[3][i].paint(g);
            }


        }
        for (int i = 0; i < 10; i++) {
            if (i < cardRemainIndex[1]) {
                cardRemains[1][i].paint(g);
            }

            if (i < phomCardIndex[0]) {
                cardPhomSet[0][i].paint(g);
            }
        }
        for (int i = 0; i < 10; i++) {
            //1
            if (i < phomCardIndex[1]) {
                cardPhomSet[1][i].paint(g);
            }

            if (i < cardFightedIndex[1]) {
                cardFighted[1][i].paint(g);
            }
            //2
            if (i < cardEatedIndex2) {
                cardEated2[i].paint(g);
            }
            if (i < cardFightedIndex[2]) {
                cardFighted[2][i].paint(g);
            }

            //3
            if (i < cardEatedIndex3) {
                cardEated3[i].paint(g);
            }
            if (i < cardFightedIndex[3]) {
                cardFighted[3][i].paint(g);
            }
        }

        if (!isViewer && !isFinishGame) {
            paintCardInHand(g);
            if (handCurseurIndex >= 0 && numberCardRemains > 0) {
                g.drawImage(handCurSeurImage, cardInHands[handCurseurIndex].getX(), cardInHands[handCurseurIndex].getY() - handCurSeurImage.getHeight() - 5 + delta, 0);
            }
        }
    }

    private void paintCardInHand(Graphics g) {
        for (int i = 0; i < numberCardRemains; i++) {
            cardInHands[i].paint(g);
            if (isDrawMarkPhomSet) {
                if (isBelongOfFlushSet[i]) {
                    g.setColor(MARK_SET_COLOR);
                    g.fillRect(cardInHands[i].getX(), cardInHands[i].getY() + 25, DISTANCE_HORIZONTAL_CARD, 2);
                }
            }
        }
    }
    //---------------------------------------------------------------------------

    private int getPosId(int id) {
        return ((id - playerId + maxPlayer) % maxPlayer);
    }

    private void addDepositCardToPhom(int fromPlayerId, int toPlayerId, int cardId, int posType) {
        Card card = new Card(cardId, Card.STATE_NORMAL, cardImages);
        int toPosId = getPosId(toPlayerId);
//        Debug.d("card :" + cardId + ",postype:" + posType);
//        Debug.d("phom set index:" + (phomCardIndex[toPosId] - 1));
        if (posType == 1) {
            phomCardIndex[toPosId] += 1;
//            Debug.d("length 1:" + (phomCardIndex[toPosId] - 1));
//            Debug.d("length 2:" + (cardPhomSet[toPosId].length));
            for (int i = phomCardIndex[toPosId] - 1; i > 0; i--) {
                cardPhomSet[toPosId][i] = cardPhomSet[toPosId][i - 1];
            }
            cardPhomSet[toPosId][0] = card;

            setPhomPosition(toPlayerId);

        } else {
            int phomSetLength = phomCardIndex[toPosId];
            cardPhomSet[toPosId][phomSetLength] = card;
            phomCardIndex[toPosId] += 1;
            setPhomPosition(toPlayerId);
        }
    }

    private void setPhomPosition(int id) {
//        int index = 0;
        int cardSetWidth = 0;
        int cardSetHeight = 0;
        int posId = ((id - playerId + maxPlayer) % maxPlayer);
        int phomSetLength = phomCardIndex[posId];
        switch (posId) {
            case 0: {
                cardSetWidth = (phomSetLength - 1) * DISTANCE_HORIZONTAL_CARD + cardWidth;
                for (int i = 0; i < phomSetLength; i++) {
                    cardPhomSet[0][i].setPosition(canvasWidth / 2 - cardSetWidth / 2 + i * DISTANCE_HORIZONTAL_CARD, positionY[0] - 10);
                }
                cardEatedIndex0 = 0;
                parent.repaint();
            }
            break;
            case 1:
                cardSetHeight = (phomSetLength - 1) * DISTANCE_VERTICAL_CARD + cardHeight;
                for (int i = 0; i < phomSetLength; i++) {
                    cardPhomSet[posId][i].setPosition(positionX[posId] - 20 + cardWidth, canvasHeight / 2 - cardSetHeight / 2 + DISTANCE_VERTICAL_CARD * i);
                }
                parent.repaint();
                break;
            case 2:
                for (int i = 0; i < phomSetLength; i++) {
                    cardPhomSet[posId][i].setPosition(positionX[posId] + DISTANCE_HORIZONTAL_CARD * i - 20, positionY[posId]);
                }
                Debug.d("phom set index 2:" + phomCardIndex[posId]);
                parent.repaint();
                break;
            case 3:
                cardSetHeight = DISTANCE_VERTICAL_CARD * (phomSetLength - 1) + cardHeight;
                for (int i = 0; i < phomSetLength; i++) {
                    cardPhomSet[posId][i].setPosition(positionX[posId] - 10, canvasHeight / 2 - cardSetHeight / 2 + i * DISTANCE_VERTICAL_CARD);
                }
                parent.repaint();
                break;
        }

    }

    private void doDepositCard() {
        int depositTarget = depositTargerArr[depositTargerIndex - 1];
        //gui bai
        for (int i = 0; i < depositCardIndex; i++) {
            Request.sendDepositCard(playerId, depositTarget, depositCardArr[i], depositPostion[i]);
            addDepositCardToPhom(playerId, depositTarget, depositCardArr[i], depositPostion[i]);
            for (int j = 0; j < numberCardRemains; j++) {
                if (depositCardArr[i] == cardInHands[j].getCardId()) {
                    removeCardInHand(j);
                    i = numberCardRemains - 1;
                }
            }
        }
        //con the gui ko
        depositNumberArr[depositTargerIndex - 1] -= 1;
        if (depositNumberArr[depositTargerIndex - 1] != 0) {
            findDepositCard(depositTarget);
            showDepositCard();
        } else {
            depositTargerIndex--;
            if (depositTargerIndex != 0) {
                depositTarget = depositTargerArr[depositTargerIndex - 1];
                findDepositCard(depositTarget);
                showDepositCard();
            } else {
                isDepositCard = false;
                parent.repaint();
            }
        }
    }

    private void removeCardInHand(int cardChooseIndex) {
        for (int i = cardChooseIndex; i < numberCardRemains - 1; i++) {
            cardInHands[i] = cardInHands[i + 1];
        }
        cardInHands[numberCardRemains - 1] = null;
        numberCardRemains--;
        Debug.d("remove :" + numberCardRemains);
        setCardPosition();
    }

    private void showDepositCard() {
        if (depositCardIndex == 0) {
            setCardPosition();
            return;
        }
        for (int i = 0; i < depositCardIndex; i++) {
            for (int j = 0; j < numberCardRemains; j++) {
                if (depositCardArr[i] == cardInHands[j].getCardId()) {
                    cardInHands[j].changeState(Card.UP);
                }
            }
        }
    }

    private int findDepositCard(int depositTarget) {
        // truyen vao targer va tra ve 1 list cac quan bai co the gui
        Debug.d("find deposit card , deposit target :" + depositTarget);
        int posIdHaPhom = (depositTarget - playerId + maxPlayer) % maxPlayer;
        Card[] cardHaPhom = cardPhomSet[posIdHaPhom];
        depositCardIndex = 0;
        for (int i = 0; i < numberCardRemains; i++) {
            int cardId = cardInHands[i].getCardId();
            if (checkDepositCard(cardId, cardHaPhom, phomCardIndex[posIdHaPhom])) {
                Debug.d("add deposit card :" + cardId);
                depositCardArr[depositCardIndex] = cardId;
                depositCardIndex++;
            }
        }

        return depositCardIndex;
    }

    private boolean checkPairDeposit(int cardDeposit, int[] cardCheck, int checkIndex) {
        Debug.d("check pair:" + cardDeposit);
        for (int i = 0; i < checkIndex - 2; i++) {
            if (cardDeposit % 13 == cardCheck[i] % 13 && cardDeposit % 13 == cardCheck[i + 1] % 13
                    && cardDeposit % 13 == cardCheck[i + 2] % 13) {
                depositPostion[depositCardIndex] = i / 3 + 1;
                return true;
            }
        }
        return false;
    }

    private boolean checkFlushDeposit(int cardDeposit, int[] cardCheck, int checkIndex) {
        Debug.d("check flush :" + cardDeposit);
        for (int i = 0; i < checkIndex - 1; i++) {
            //tim dong  chat
            if (cardDeposit / 13 == cardCheck[i] / 13) {
                int countFlush = 0;
                Debug.d("start find flush :" + cardCheck[i]);
                //tim day, bat con cuoi
                for (int j = i; j < checkIndex; j++) {
                    if (cardCheck[i] == cardCheck[j] - j + i) {
                        Debug.d("flush :" + cardCheck[j]);
                        countFlush++;
                    }
                }
                // co the  ghep dau hoac ghep cuoi
                if ((cardDeposit == cardCheck[i] - 1
                        || (cardDeposit == cardCheck[i + countFlush - 1] + 1)) && countFlush >= 3) {
                    depositPostion[depositCardIndex] = (i + countFlush - 1) / 3 + 1;
                    return true;
                }
            }
        }
        return false;
    }

    private boolean checkDepositCard(int cardDeposit, Card[] cardHaPhom, int cardHaPhomIndex) {
        int cardCheckIndex = 0;
        for (int i = 0; i < cardHaPhomIndex; i++) {
            cardCheckIdArr[cardCheckIndex] = cardHaPhom[i].getCardId();
            cardCheckIndex++;
        }
        if (checkPairDeposit(cardDeposit, cardCheckIdArr, cardCheckIndex)) {
            Debug.d("deposit pair");
            return true;
        }

        if (checkFlushDeposit(cardDeposit, cardCheckIdArr, cardCheckIndex)) {
            Debug.d("deposit flush");
            return true;
        }
        Debug.d("ko tim thay");
        return false;
    }

    void doGameKeyCenter() {
        if (isLoading) {
            return;
        }
        try {
            if (isDepositCard && !isViewer) {
                doDepositCard();
                return;
            }
            if (isFinishGame) {
                if (!isViewer) {
                    Request.changeReadyState(0);
                    showWaitingRoom();
                }
                if (!isViewer) {
                    if (playerWinByUId == -1) {
                        Request.finishPhom(playeIdWin);
                    } else {
                        Request.finishPhom(playerWinByUId);
                    }
                }
                return;
            }
            if (gameTurn == playerId && !isViewer) {
                if (isGetMoreCard) {
                    doEatCard();
                    return;
                }
                if (isHaPhom) {
                    isHaPhom = false;
                    doHaPhom();
                    Debug.d("ha phom");
                    return;
                }
                checkFightCard();
            }
            parent.repaint();
        } catch (Exception ex) {
        }
    }

    private void checkFightCard() {
        int numberCardChooses = 0;
        int cardChooseIndex = 0;
        for (int i = 0; i < numberCardRemains; i++) {
            if (cardInHands[i].getState() == Card.STATE_HEIGHT) {
                numberCardChooses++;
                cardChooseIndex = i;
            }
        }
        if (numberCardChooses == 0) {
            dialogString = "Hãy chọn một quân";
            parent.repaint();
        } else if (numberCardChooses == 1) {
            if (cardInHands[cardChooseIndex].isCardEated) {
                dialogString = "Không được phá phỏm đã ăn";
                parent.repaint();
                return;
            }
            fightChooseCard(cardChooseIndex);
            return;
        } else {
            dialogString = "Chỉ chọn một quân";
            parent.repaint();
            return;
        }
    }

    private void fightChooseCard(int cardChooseIndex) {
        Request.fightCardPhom(playerId, cardInHands[cardChooseIndex].getCardId());
        playerFightid = playerId;
        cardCanbeEated = cardInHands[cardChooseIndex];
        addCardToFightedList(cardCanbeEated, playerId);
        removeCardInHand(cardChooseIndex);
        Debug.d("number card fight");
        if (cardFightedIndex[0] == 4) {
            int countRemainCard = 0;
            int[] cardRemainIds = new int[NUMBER_CARD_IN_HANDS];
            for (int i = 0; i < numberCardRemains; i++) {
                cardRemainIds[countRemainCard] = cardInHands[i].getCardId();
                countRemainCard++;
            }
            Request.finishPhom(cardRemainIds, countRemainCard);
            int numberPlayerFinish = countPlayerFinish();
            if (numberPlayerFinish == numberPlayers) {
                Request.fnMessgePhom();
                isFinishGame = true;
            }
        }
        extractPhom();
        handCurseurIndex = cardChooseIndex;
        if (handCurseurIndex >= numberCardRemains) {
            handCurseurIndex = numberCardRemains - 1;
        }
        if (!isFinishGame) {
            nextGameTurn();
        }
        parent.repaint();
    }

    private int markPhomSet() {
        int numberCardInPhom = markPhom();

        for (int i = 0; i < numberCardRemains - 2; i++) {
            if (isBelongOfFlushSet[i] && isBelongOfFlushSet[i + 1] && isBelongOfFlushSet[i + 2]) {
                //check phom doc
                isBelongOfFlushSet[i] = false;
                if (cardInHands[i].getCardId() / 13 == cardInHands[i + 1].getCardId() / 13
                        && cardInHands[i].getCardId() / 13 == cardInHands[i + 2].getCardId() / 13) {
                    isBelongOfFlushSet[i] = true;
                    continue;
                }
                if (i >= 1) {
                    if (cardInHands[i].getCardId() / 13 == cardInHands[i + 1].getCardId() / 13
                            && cardInHands[i].getCardId() / 13 == cardInHands[i - 1].getCardId() / 13) {
                        isBelongOfFlushSet[i] = true;
//                        Debug.d("2");
                        continue;
                    }
                }
                if (i >= 2) {
                    if (cardInHands[i].getCardId() / 13 == cardInHands[i - 1].getCardId() / 13
                            && cardInHands[i].getCardId() / 13 == cardInHands[i - 2].getCardId() / 13) {
                        isBelongOfFlushSet[i] = true;
//                        Debug.d("3");
                        continue;
                    }
                }
//                Debug.d("check phom ngang");
                if (cardInHands[i].getCardId() % 13 == cardInHands[i + 1].getCardId() % 13
                        && cardInHands[i].getCardId() % 13 == cardInHands[i + 2].getCardId() % 13) {
                    isBelongOfFlushSet[i] = true;
//                    Debug.d("1");
//                    Debug.d("card i :" + cardInHands[i].getCardId());
//                    Debug.d("card i+1 :" + cardInHands[i + 1].getCardId());
//                    Debug.d("card i+2 :" + cardInHands[i + 2].getCardId());
                    continue;
                }
                if (i >= 1) {
                    if (cardInHands[i].getCardId() % 13 == cardInHands[i + 1].getCardId() % 13
                            && cardInHands[i].getCardId() % 13 == cardInHands[i - 1].getCardId() % 13) {
                        isBelongOfFlushSet[i] = true;
//                        Debug.d("2");
                        continue;
                    }
                }
                if (i >= 2) {
                    if (cardInHands[i].getCardId() % 13 == cardInHands[i - 1].getCardId() % 13
                            && cardInHands[i].getCardId() % 13 == cardInHands[i - 2].getCardId() % 13) {
                        isBelongOfFlushSet[i] = true;
//                        Debug.d("3");
                        continue;
                    }
                }

            } else {
                if (i == 1 && isBelongOfFlushSet[i]) {
                    if (isBelongOfFlushSet[i - 1] && isBelongOfFlushSet[i + 1]) {
                        if (cardInHands[i].getCardId() / 13 == cardInHands[i + 1].getCardId() / 13
                                && cardInHands[i].getCardId() / 13 == cardInHands[i - 1].getCardId() / 13) {
                            isBelongOfFlushSet[i] = true;
                            continue;

                        }
                        if (cardInHands[i].getCardId() % 13 == cardInHands[i + 1].getCardId() % 13
                                && cardInHands[i].getCardId() % 13 == cardInHands[i - 1].getCardId() % 13) {
                            isBelongOfFlushSet[i] = true;
                            continue;

                        }
                    }
                } else if (i > 1 && isBelongOfFlushSet[i]) {
                    if (isBelongOfFlushSet[i - 1] && isBelongOfFlushSet[i - 2]) {
                        if (cardInHands[i].getCardId() / 13 == cardInHands[i - 1].getCardId() / 13
                                && cardInHands[i].getCardId() / 13 == cardInHands[i - 2].getCardId() / 13) {
                            isBelongOfFlushSet[i] = true;
                            continue;

                        }
                        if (cardInHands[i].getCardId() % 13 == cardInHands[i - 1].getCardId() % 13
                                && cardInHands[i].getCardId() % 13 == cardInHands[i - 2].getCardId() % 13) {
                            isBelongOfFlushSet[i] = true;
                            continue;

                        }
                    }

                    if (isBelongOfFlushSet[i - 1] && isBelongOfFlushSet[i + 1]) {
                        if (cardInHands[i].getCardId() / 13 == cardInHands[i + 1].getCardId() / 13
                                && cardInHands[i].getCardId() / 13 == cardInHands[i - 1].getCardId() / 13) {
                            isBelongOfFlushSet[i] = true;
                            continue;

                        }
                        if (cardInHands[i].getCardId() % 13 == cardInHands[i + 1].getCardId() % 13
                                && cardInHands[i].getCardId() % 13 == cardInHands[i - 1].getCardId() % 13) {
                            isBelongOfFlushSet[i] = true;
                            continue;

                        }
                    }
                }
                isBelongOfFlushSet[i] = false;
                if (i == numberCardRemains - 3) {
                    isBelongOfFlushSet[i + 2] = false;
                    isBelongOfFlushSet[i + 1] = false;

                }
            }
        }
        parent.repaint();
        return numberCardInPhom;
    }

    private int countPlayerFinish() {
        int numberFinish = 0;
        for (int i = 0; i < maxPlayer; i++) {
            if (gameData.isPlays[i]) {
                int posId = getPosId(i);
                if (cardFightedIndex[posId] == 4) {
                    numberFinish++;
                }
            }
        }
        return numberFinish;
    }

    private void nextGameTurn() {

//        Debug.d("pre turn  :" + gameTurn);
        int preTurn = gameTurn;
        for (int i = preTurn + 1; i < maxPlayer + preTurn; i++) {
            if (gameData.isPlays[i % maxPlayer]) {
                gameTurn = i % maxPlayer;
                break;
            }
        }
//        Debug.d("current turn  :" + gameTurn);
        isGetMoreCard = true;
        timeForThink = TIME_FOR_THINK;
        parent.repaint();
    }

    private void doHaPhom() {
        extractPhom();
        if (numberPhoms > 0) {
            int phomSendToServerIndex = 0;
            int[] phomSendToServerId = new int[NUMBER_CARD_IN_HANDS];

            for (int i = 0; i < phomIndex[0]; i++) {
                phomSendToServerId[phomSendToServerIndex] = phomSet[0][i];
                phomSendToServerIndex++;
            }

            for (int i = 0; i < phomIndex[1]; i++) {
                phomSendToServerId[phomSendToServerIndex] = phomSet[1][i];
                phomSendToServerIndex++;
            }

            for (int i = 0; i < phomIndex[2]; i++) {
                phomSendToServerId[phomSendToServerIndex] = phomSet[2][i];
                phomSendToServerIndex++;
            }

            Request.haphom(playerId, phomSendToServerId, phomSendToServerIndex);
            movePhomSet(phomSendToServerId, phomSendToServerIndex, playerId);
            handCurseurIndex = 0;
            isHavePhom = true;
        } else {
            isNotHavePhom[playerId] = true;
        }

        if (gameRule == Constants.PHOM_GUI && isHavePhom) {
            depositCard();
        }
        isDrawMarkPhomSet = false;
    }

    private void addCardToFightedList(Card cardToAdd, int id) {
        int cardFightHeight = 0;
        int posId = ((id - playerId + maxPlayer) % maxPlayer);
//        Debug.d("post id:" + posId);
//        Debug.d("card index :" + cardToAdd.getCardId());
//        Debug.d("add to index :" + cardFightedIndex[posId]);
        switch (posId) {
            case 0:
                cardFighted[posId][cardFightedIndex[posId]] = cardToAdd;
                cardFightedIndex[posId] += 1;
                int cardFightWidth = DISTANCE_HORIZONTAL_CARD * (cardFightedIndex[0] - 1) + cardWidth;
                for (int i = 0; i < cardFightedIndex[0]; i++) {
                    cardFighted[0][i].setPosition(canvasWidth / 2 - cardFightWidth / 2 + i * DISTANCE_HORIZONTAL_CARD, positionY[0] - 30);
                }
                parent.repaint();
                break;
            case 1:
                cardFighted[posId][cardFightedIndex[posId]] = cardToAdd;
                cardFightedIndex[posId] += 1;
                cardFightHeight = (DISTANCE_VERTICAL_CARD - 1) * cardFightedIndex[1] + cardHeight;
                for (int i = 0; i < cardFightedIndex[1]; i++) {
                    cardFighted[1][i].setPosition(positionX[posId] - 20, canvasHeight / 2 - cardFightHeight / 2 + i * DISTANCE_VERTICAL_CARD);
                }
                parent.repaint();
                break;
            case 2:
                cardFighted[posId][cardFightedIndex[posId]] = cardToAdd;
                cardFightedIndex[posId] += 1;
                for (int i = 0; i < cardFightedIndex[2]; i++) {
                    cardFighted[2][i].setPosition(positionX[posId] + DISTANCE_HORIZONTAL_CARD * i - 30, positionY[posId] + 20);
                }
                parent.repaint();
                break;
            case 3:
                cardFighted[posId][cardFightedIndex[posId]] = cardToAdd;
                cardFightedIndex[posId] += 1;
                cardFightHeight = (DISTANCE_VERTICAL_CARD - 1) * cardFightedIndex[3] + cardHeight;
                for (int i = 0; i < cardFightedIndex[3]; i++) {
                    cardFighted[3][i].setPosition(positionX[posId] + 10, canvasHeight / 2 - cardFightHeight / 2 + i * DISTANCE_VERTICAL_CARD);
                }
                parent.repaint();
                break;
        }

    }

    private void showRemainCard(int id, int numberCard) {
        int cardRemainHeight = 0;
        int posId = ((id - playerId + maxPlayer) % maxPlayer);
        switch (posId) {
            case 0:
                int cardRemainWidth = DISTANCE_HORIZONTAL_CARD * (numberCard - 1) + cardWidth;
                for (int i = 0; i < numberCard; i++) {
                    cardRemains[0][i].setPosition(canvasWidth / 2 - cardRemainWidth / 2 + i * DISTANCE_HORIZONTAL_CARD, positionY[0] - 30);
                }
                cardRemainIndex[0] = numberCard;
                cardFightedIndex[0] = 0;
                parent.repaint();
                break;
            case 1:
                cardRemainHeight = (DISTANCE_VERTICAL_CARD - 1) * numberCard + cardHeight;
                for (int i = 0; i < numberCard; i++) {
                    cardRemains[1][i].setPosition(positionX[posId] - 20, canvasHeight / 2 - cardRemainHeight / 2 + i * DISTANCE_VERTICAL_CARD);
                }
                cardRemainIndex[1] = numberCard;
                cardFightedIndex[1] = 0;
                parent.repaint();
                break;
            case 2:
                for (int i = 0; i < numberCard; i++) {
                    cardRemains[2][i].setPosition(positionX[posId] + DISTANCE_HORIZONTAL_CARD * i - 30, positionY[posId] + 20);
                }
                cardRemainIndex[2] = numberCard;
                cardFightedIndex[2] = 0;
                parent.repaint();
                break;
            case 3:
                cardRemainHeight = (DISTANCE_VERTICAL_CARD - 1) * numberCard + cardHeight;
                for (int i = 0; i < numberCard; i++) {
                    cardRemains[3][i].setPosition(positionX[posId] + 10, canvasHeight / 2 - cardRemainHeight / 2 + i * DISTANCE_VERTICAL_CARD);
                }
                cardRemainIndex[3] = numberCard;
                cardFightedIndex[3] = 0;
                parent.repaint();
                break;
        }

    }

    private void movePhomSet(int[] phomSet, int phomSetLength, int id) {
        int index = 0;
        int cardSetWidth = 0;
        int cardSetHeight = 0;
        int posId = ((id - playerId + maxPlayer) % maxPlayer);
        int startIndex = phomCardIndex[posId];
        switch (posId) {
            case 0:
                if (!isViewer) {
                    for (int i = 0; i < phomSetLength; i++) {
                        for (int j = 0; j < numberCardRemains; j++) {
                            if (phomSet[i] == cardInHands[j].getCardId()) {
                                Card card = cardInHands[j];
                                index = phomCardIndex[0];
                                cardPhomSet[0][index] = card;
                                index += 1;
                                phomCardIndex[0] = index;
                                for (int k = j; k < numberCardRemains - 1; k++) {
                                    cardInHands[k] = cardInHands[k + 1];
                                }
                                cardInHands[numberCardRemains - 1] = null;
                                numberCardRemains--;
                            }
                        }
                    }
                    index = phomCardIndex[0];
                    cardSetWidth = (index - 1) * DISTANCE_HORIZONTAL_CARD + cardWidth;
                    for (int i = 0; i < index; i++) {
                        cardPhomSet[0][i].setPosition(canvasWidth / 2 - cardSetWidth / 2 + i * DISTANCE_HORIZONTAL_CARD, positionY[0] - 10);
                    }
                    setCardPosition();
                    cardEatedIndex0 = 0;
                    parent.repaint();
                } else {
                    cardSetWidth = (phomSetLength - 1) * DISTANCE_HORIZONTAL_CARD + cardWidth;
                    for (int i = 0; i < phomSetLength; i++) {
                        cardPhomSet[posId][i] = new Card(phomSet[i], Card.STATE_NORMAL, cardImages);
                        cardPhomSet[0][i].setPosition(canvasWidth / 2 - cardSetWidth / 2 + i * DISTANCE_HORIZONTAL_CARD, positionY[0] - 10);
                        phomCardIndex[posId]++;
                    }
                    cardEatedIndex0 = 0;
                    parent.repaint();
                }
                break;
            case 1:
                cardSetHeight = (phomSetLength + startIndex - 1) * DISTANCE_VERTICAL_CARD + cardHeight;
                for (int i = 0; i < startIndex; i++) {
                    cardPhomSet[posId][i].setPosition(positionX[posId] - 20 + cardWidth, canvasHeight / 2 - cardSetHeight / 2 + DISTANCE_VERTICAL_CARD * i);
                }
                for (int i = startIndex; i < phomSetLength + startIndex; i++) {
                    cardPhomSet[posId][i] = new Card(phomSet[i - startIndex], Card.STATE_NORMAL, cardImages);
                    cardPhomSet[posId][i].setPosition(positionX[posId] - 20 + cardWidth, canvasHeight / 2 - cardSetHeight / 2 + DISTANCE_VERTICAL_CARD * i);
                    phomCardIndex[posId]++;
                }
                cardEatedIndex1 = 0;
                parent.repaint();

                break;
            case 2:

                for (int i = startIndex; i < phomSetLength + startIndex; i++) {
                    cardPhomSet[posId][i] = new Card(phomSet[i - startIndex], Card.STATE_NORMAL, cardImages);
                    cardPhomSet[posId][i].setPosition(positionX[posId] + DISTANCE_HORIZONTAL_CARD * i - 35, positionY[posId]);
                    phomCardIndex[posId]++;
                }
                cardEatedIndex2 = 0;
                parent.repaint();
                break;
            case 3:
                cardSetHeight = DISTANCE_VERTICAL_CARD * (phomSetLength + startIndex - 1) + cardHeight;
                for (int i = 0; i < startIndex; i++) {
                    cardPhomSet[posId][i].setPosition(positionX[posId] - 10, canvasHeight / 2 - cardSetHeight / 2 + i * DISTANCE_VERTICAL_CARD);
                }
                for (int i = startIndex; i < phomSetLength + startIndex; i++) {
                    cardPhomSet[posId][i] = new Card(phomSet[i - startIndex], Card.STATE_NORMAL, cardImages);
                    cardPhomSet[posId][i].setPosition(positionX[posId] - 10, canvasHeight / 2 - cardSetHeight / 2 + i * DISTANCE_VERTICAL_CARD);
                    phomCardIndex[posId]++;
                }
                cardEatedIndex3 = 0;
                parent.repaint();
                break;
        }

    }

    private boolean canDepositCard() {
        //ko phai thang ha truoc
//        Debug.d("player id :" + playerId);
//        Debug.d("firt ha :" + firstHaPhom);
        if (playerId == firstHaPhom) {
            return false;
        }
        //tim dich ha
//        Debug.d("number player :" + numberPlayers);
        depositTargerIndex = 0;
        for (int i = 0; i < maxPlayer; i++) {
            int idCheck = (playerId + i) % maxPlayer;
//            Debug.d("id check :" + idCheck);
            int posId = (idCheck - playerId + maxPlayer) % maxPlayer;
            if (phomCardIndex[posId] > 0 && posId != 0) {
                depositNumberArr[depositTargerIndex] = findDepositCard(idCheck);
                if (depositNumberArr[depositTargerIndex] > 0) {
                    //add vao list co the gui
//                    Debug.d("add to deposit target :" + idCheck);
                    depositTargerArr[depositTargerIndex] = idCheck;
                    depositTargerIndex++;
                }
            }
        }
        Debug.d("list target deposit :" + depositTargerIndex);
        if (depositTargerIndex > 0) {
            depositTargerListLength = depositTargerIndex;
            return true;
        }
        return false;
    }

    private void depositCard() {
        Debug.d("deposit Card");
        if (canDepositCard()) {
            findDepositCard(depositTargerArr[depositTargerIndex - 1]);
            showDepositCard();
            isDepositCard = true;
            parent.repaint();
        }
    }

    private boolean checkCardEat(int[] cardCheck) {
        sortCardPhom(cardCheck, 3);

        if (Debug.isTest) {
            for (int i = 0; i < 3; i++) {
                Debug.d("card check to eat :" + cardCheckIdArr[i]);
            }
        }
        if (cardCheck[0] % 13 == cardCheck[1] % 13 && cardCheck[1] % 13 == cardCheck[2] % 13) {
            eatSetType = PAIR_SET;
            return true;
        }
        if (cardCheck[1] == cardCheck[0] + 1 && cardCheck[2] == cardCheck[1] + 1) {
            eatSetType = FLUSH_SET;
            return true;
        }

        //  Debug.d("ko an duoc");
        return false;
    }

    private int getEatType() {
        if (cardFightedIndex[getPosId(playerFightid)] == 4) {
            return 2;
        }
        int count = 0;
        for (int i = 0; i < maxPlayer; i++) {
            if (gameData.isPlays[i] && cardFightedIndex[i] == 3) {
                count++;
            }
        }
        if (count == numberPlayers) {
            return 2;
        }
        return 1;
    }

    private void doEatCard() {
        int numberCardChooses = 0;
        int cardChooseIndex = 0;
        int cardCheckIndex = 0;
        boolean notPermission = false;
        for (int i = 0; i < numberCardRemains; i++) {
            if (cardInHands[i].getState() == Card.STATE_HEIGHT) {
                cardCheckIdArr[cardCheckIndex] = cardInHands[i].getCardId();
                Debug.d("card up to eat :" + cardCheckIdArr[cardCheckIndex]);
                if (cardInHands[i].isCardEated) {
                    notPermission = true;
                    break;
                }
                cardCheckIndex++;
                numberCardChooses++;
                cardChooseIndex = i;
            }
        }
        if (notPermission) {
            dialogString = "Không thể phá phỏm đã ăn";
            parent.repaint();
            return;
        }
        if (numberCardChooses == 0) {
            if (checkAutoEatCard(cardCanbeEated.getCardId())) {
                Request.eatCardPhom(playerFightid, cardCanbeEated.getCardId(), 1);
                cardCanbeEated.initializeMove(cardCanbeEated.getX(), cardCanbeEated.getY(),
                        cardInHands[cardChooseIndex].getX(), cardInHands[cardChooseIndex].getY(), 3);
                playerEatId = playerId;
                isEatCard = true;
                isGetMoreCard = false;
                parent.repaint();
            } else {
                dialogString = "Không thể ăn được bài";
                parent.repaint();
            }
        } else if (numberCardChooses == 2) {
            cardCheckIdArr[cardCheckIndex] = cardCanbeEated.getCardId();
            if (checkCardEat(cardCheckIdArr)) {
                int eatType = getEatType();
                Request.eatCardPhom(playerFightid, cardCanbeEated.getCardId(), eatType);
                cardCanbeEated.initializeMove(cardCanbeEated.getX(), cardCanbeEated.getY(),
                        cardInHands[cardChooseIndex].getX(), cardInHands[cardChooseIndex].getY(), 3);
                playerEatId = playerId;
                isEatCard = true;
                isGetMoreCard = false;
                parent.repaint();
            } else {
                dialogString = "Không thể ăn được bài";
                parent.repaint();
            }
        } else {
            if (!isViewer) {
                dialogString = "Bạn phải nâng hai quân bài lên";
                parent.repaint();
            }
            return;
        }
    }
//--------------------------------------------------------------------------------

    public void setListSubMenu() {
        subMenu.setList(new String[]{"Xếp bài", "Rời bàn", "Loa"});
    }

    protected void doSubMenu() {
        if (!isViewer) {
            switch (subMenu.getSelectedIndex()) {
                case 0:
                    sortCardBySet();
                    isShowSubMenu = false;
                    subMenu.setVisible(false);
                    parent.repaint();
                    break;
                case 1:
                    super.doSubMenu();
                    break;
                case 2:
                    //loa
                    isShowSubMenu = false;
                    isShowSpeaker = true;
                    speakerBox.setText("");
                    parent.repaint();
                    break;
            }
        } else {
            switch (subMenu.getSelectedIndex()) {
                case 0:
                    super.doSubMenu();
                    break;
                case 1:
                    //loa
                    isShowSubMenu = false;
                    isShowSpeaker = true;
                    speakerBox.setText("");
                    parent.repaint();
                    break;
            }
        }
    }

    public void doWhenHalfTime() {
        if (gameTurn == playerId && !isFinishGame) {
            if (isDepositCard && !isViewer) {
                doDepositCard();
                return;
            }
            if (isGetMoreCard) {
                Request.getCardDraw();
                isGetMoreCard = false;
                parent.repaint();
            }
        }
    }

    public void doWhenTimeExpired() {
        if (isFinishGame) {
            return;
        }
        if (timeForThink == 10) {
            if (!isViewer) {
                doWhenHalfTime();
            }
            return;
        }
        if (timeForThink == 5) {
            if (!isViewer) {
                if (isHaPhom) {
                    isHaPhom = false;
                    doHaPhom();
                    Debug.d("ha phom");
                }
                return;
            }
        }
        if (timeForThink == 0) {
            if (!isViewer) {
                if (gameTurn == playerId) {
                    fightChooseCard(numberCardRemains - 1);
                }
            }
            isDrawClock = false;
        }
    }

    void doCardGameLoop() {
        if (cardMoveIndex > 0) {
            moveCard();
            parent.repaint();
        }
        if (countFrame % 8 == 0) {
            isShowPlayerName = !isShowPlayerName;
            parent.repaint();
        }
        if (isEatCard && cardCanbeEated != null) {
            moveEatedCard();
        }
    }

    private void addEatedCardToList() {
        if (gameTurn == playerId && !isViewer) {
            cardInHands[numberCardRemains] = cardCanbeEated;
            numberCardRemains++;
            cardCanbeEated = null;
            isEatCard = false;
            Debug.d("eat from player id :" + playerFightid);
            removeCardFromFightedList(playerFightid);
            numberEats++;

            //TODO: truong hop pha phom
//            int cardChooseIndex = findRemainCard(0);
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < numberCardRemains; j++) {
                    if (cardInHands[j].getCardId() == cardCheckIdArr[i]) {
                        Debug.d("card eat :" + cardCheckIdArr[i]);
                        cardInHands[j].isCardEated = true;
                        cardInHands[j].eatId = (numberEats - 1);
                        cardInHands[j].phomId = i;
                    }
                }
            }

            sortCardBySet();
            setCardPosition();
            extractPhom();

        } else {
            int cardEatHeight = 0;
            int posId = ((playerEatId - playerId + maxPlayer) % maxPlayer);
            switch (posId) {
                case 0:
                    if (isViewer) {
                        cardEated0[cardEatedIndex0] = cardCanbeEated;
                        cardEatedIndex0++;
                        int cardEatWidth = (cardEatedIndex0 - 1) * DISTANCE_HORIZONTAL_CARD + cardWidth;
                        for (int i = 0; i < cardEatedIndex0; i++) {
                            cardEated0[i].setPosition(canvasWidth / 2 - cardEatWidth / 2 + i * DISTANCE_HORIZONTAL_CARD, positionY[0] - 10);
                        }
                        parent.repaint();
                    }
                    break;
                case 1:
                    cardEated1[cardEatedIndex1] = cardCanbeEated;
                    cardEatedIndex1++;
                    cardEatHeight = DISTANCE_VERTICAL_CARD * (cardEatedIndex1 - 1) + cardHeight;
                    for (int i = 0; i < cardEatedIndex1; i++) {
                        cardEated1[i].setPosition(positionX[posId] - 20 + cardWidth, canvasHeight / 2 - cardEatHeight / 2 + DISTANCE_VERTICAL_CARD * i);
                    }
                    parent.repaint();
                    break;
                case 2:
                    cardEated2[cardEatedIndex2] = cardCanbeEated;
                    cardEatedIndex2++;
                    for (int i = 0; i < cardEatedIndex2; i++) {
                        cardEated2[i].setPosition(positionX[posId] + DISTANCE_HORIZONTAL_CARD * i - 20, positionY[posId]);
                    }
                    parent.repaint();
                    break;
                case 3:
                    cardEated3[cardEatedIndex3] = cardCanbeEated;
                    cardEatedIndex3++;
                    cardEatHeight = DISTANCE_VERTICAL_CARD * (cardEatedIndex3 - 1) + cardHeight;
                    for (int i = 0; i < cardEatedIndex3; i++) {
                        cardEated3[i].setPosition(positionX[posId] - 10, canvasHeight / 2 - cardEatHeight / 2 + i * DISTANCE_VERTICAL_CARD);
                    }
                    parent.repaint();
                    break;
            }
            cardCanbeEated = null;
            isEatCard = false;
            removeCardFromFightedList(playerFightid);
            parent.repaint();

        }
    }

    private void moveEatedCard() {
        // Debug.d("move eat card");
        try {
            cardCanbeEated.move();
            if (cardCanbeEated.getState() == Card.STATE_NORMAL) {
                addEatedCardToList();
//            Debug.d("firt ha phom :" + firstHaPhom);
//            Debug.d("player bi an :" + playerFightid);
//                if (playerFightid != firstHaPhom) {
                changeFirstHaPhom();
//                }
                firstHaPhom = (++firstHaPhom) % numberPlayers;
                if (!isViewer) {
                    checkHaphom();
                }
                if (Debug.isTest) {
                    isHaPhom = true;
                }

            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        parent.repaint();
    }

    private void changeFirstHaPhom() {
        Debug.d("chuyen ha phom dau:" + firstHaPhom);
        Debug.d("thang an :" + gameTurn);
        Debug.d("thang bi an :" + playerFightid);
        for (int i = playerEatId; i < playerEatId + maxPlayer; i++) {
            if (cardFightedIndex[getPosId(i % maxPlayer)] > cardFightedIndex[getPosId(playerFightid)]) {
                Card cardTransfer = removeCardFromFightedList(i % maxPlayer);
                addCardToFightedList(cardTransfer, playerFightid);
                Debug.d("tranfer card from :" + i);
                break;
            }
        }
    }

    private Card removeCardFromFightedList(int id) {
        int posId = (id - playerId + maxPlayer) % maxPlayer;
        int index = cardFightedIndex[posId];
        int cardFightHeight = 0;
//        Debug.d("index remove :" + index);
//        Debug.d("posId :" + posId);
        Card cardRemove = cardFighted[posId][index - 1];
//        Debug.d("card id remove :" + cardRemove.getCardId());

        switch (posId) {
            case 0:
                cardFighted[0][index - 1] = null;
                cardFightedIndex[0]--;
                int cardFightWidth = DISTANCE_HORIZONTAL_CARD * (cardFightedIndex[0] - 1) + cardWidth;
                for (int i = 0; i < cardFightedIndex[0]; i++) {
                    cardFighted[0][i].setPosition(canvasWidth / 2 - cardFightWidth / 2 + i * DISTANCE_HORIZONTAL_CARD, positionY[0] - 30);
                }
                parent.repaint();
                break;
            case 1:
                cardFighted[1][index - 1] = null;
                cardFightedIndex[1]--;
                cardFightHeight = (DISTANCE_VERTICAL_CARD - 1) * cardFightedIndex[1] + cardHeight;
                for (int i = 0; i < cardFightedIndex[1]; i++) {
                    cardFighted[1][i].setPosition(positionX[posId] - 20, canvasHeight / 2 - cardFightHeight / 2 + i * DISTANCE_VERTICAL_CARD);
                }
                parent.repaint();
                break;
            case 2:
                cardFighted[2][index - 1] = null;
                cardFightedIndex[2]--;
                for (int i = 0; i < cardFightedIndex[2]; i++) {
                    cardFighted[2][i].setPosition(positionX[posId] + DISTANCE_HORIZONTAL_CARD * i - 30, positionY[posId] + 20);
                }
                parent.repaint();
                break;
            case 3:
                cardFighted[3][index - 1] = null;
                cardFightedIndex[3]--;
                cardFightHeight = (DISTANCE_VERTICAL_CARD - 1) * cardFightedIndex[3] + cardHeight;
                for (int i = 0; i < cardFightedIndex[3]; i++) {
                    cardFighted[3][i].setPosition(positionX[posId] + 10, canvasHeight / 2 - cardFightHeight / 2 + i * DISTANCE_VERTICAL_CARD);
                }
                parent.repaint();
                break;
        }
        return cardRemove;
    }

    private void moveCard() {
        try {
            for (int i = 0; i < cardMoveIndex; i++) {
                cardMoves[i].move();
                if (cardMoves[cardMoveIndex - 1].getState() == Card.STATE_NORMAL) {
                    try {
                        if (isMoveDrawCard) {
                            isMoveDrawCard = false;
                            Card card = cardMoves[i];
                            Debug.d("number card remain :" + numberCardRemains);
                            cardInHands[numberCardRemains] = card;
                            //     card.setImage(cardImages[card.getCardId()]);
                            if (isMoveBcCard) {
                                isMoveBcCard = false;
                                card.setCardId(cardBcId);
                            }
                            numberCardRemains++;
                            cardMoveIndex = 0;
                            setCardPosition();
                            extractPhom();
                            checkHaphom();
                            parent.repaint();
                            break;
                        }
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }

            }
        } catch (Exception ex) {
        }

    }

    private void checkHaphom() {
        if (gameTurn == playerId) {
            if (cardFightedIndex[0] == 3) {
                isHaPhom = true;
            } else {
                isHaPhom = false;
            }
        }
    }
    //---------------------------------------------------------------------

    private void changeTargetDeposit() {
        setCardPosition();
        depositTargerIndex--;
        if (depositTargerIndex == 0) {
            depositTargerIndex = depositTargerListLength;
        }
        Debug.d("change deposit:" + depositTargerIndex);
        int depositTarget = depositTargerArr[depositTargerIndex - 1];
        findDepositCard(depositTarget);
        showDepositCard();
        parent.repaint();
    }

    public void doSoftKeyLeft() {
        if (isDepositCard) {
            changeTargetDeposit();
            return;
        }
        super.doSoftKeyLeft();
    }

    protected void doGameSoftKeyLeft() {
        if (isDepositCard) {
            changeTargetDeposit();
            return;
        }
    }

    protected void doGameSoftKeyRight() {
        if (isDepositCard) {
            isDepositCard = false;
            setCardPosition();
            parent.repaint();
        }

        if (gameTurn == playerId && isGetMoreCard) {
            Request.getCardDraw();
            isLoading = true;
            isGetMoreCard = false;
            parent.repaint();
            return;
        }
    }

    public void doKeyLeft() {
        if (isViewer) {
            return;
        }
        super.doKeyLeft();
        markPhomSet();

    }

    public void doKeyRight() {
        if (isViewer) {
            return;
        }
        super.doKeyRight();
        markPhomSet();
    }

//---------------------------------------------------------------------------------
    private void processBcMessage(int cardDrawId) {
        cardBcId = cardDrawId;
        Card cardDraw = new Card(52, Card.STATE_MOVE, cardImages);
        cardDraw.initializeMove(canvasWidth / 2, canvasHeight / 2, positionX[0], positionY[0], 2);
        cardMoves[cardMoveIndex] = cardDraw;
        cardMoveIndex++;
        isMoveDrawCard = true;
        isMoveBcCard = true;
    }

    private void processEaMessage() {
        try {
            int posId = ((gameTurn - playerId + maxPlayer) % maxPlayer);
            if (cardCanbeEated != null) {
                cardCanbeEated.initializeMove(cardCanbeEated.getX(), cardCanbeEated.getY(), positionX[posId], positionY[posId], 8);
            }
            isEatCard = true;
            playerEatId = gameTurn;
            parent.repaint();
        } catch (Exception ex) {
        }
    }

    public void processMessage(String[] part) {
        super.processMessage(part);
        if (part[0].equals("BC")) {
            int cardDrawId = Integer.parseInt(part[1]);
            processBcMessage(cardDrawId);
            isLoading = false;
            parent.repaint();
            return;
        }
        if (part[0].equals("FN")) {
            //fn|palyerId|result|cardId...
            int playerFinishId = Integer.parseInt(part[1]);
            int result = Integer.parseInt(part[2]);
            resultOrder[playerFinishId] = result;
            Debug.d("id :" + playerFinishId + ",result :" + result);
            if (result == 0) {
                playeIdWin = playerFinishId;
            }
            if (result == 4 && playerFinishId == playerId && !isViewer) {
                dialogString = "Bạn nên mua thịt cho để giải đen.";
            }
            for (int i = 3; i < part.length; i++) {
                cardRemains[getPosId(playerFinishId)][i - 3] = new Card(Integer.parseInt(part[i]), Card.STATE_NORMAL, cardImages);
            }
            Debug.d("length:" + (part.length - 3));
            showRemainCard(playerFinishId, part.length - 3);
            countFnReceive++;
            if ((countFnReceive == numberPlayers)
                    || (isViewer && countFnReceive == numberPlayers - 1)) {
                isDrawResult = true;
                isFinishGame = true;
            }
            Debug.d("number player :" + numberPlayers);
            Debug.d("fn receive :" + countFnReceive);
            Debug.d("is finish game :" + isFinishGame);
            parent.repaint();
            return;
        }
        if (part[0].equals("U")) {
            playerWinByUId = Integer.parseInt(part[1]);
            Debug.d("player u :" + playerWinByUId);
            cardEatedIndex0 = 0;
            cardEatedIndex1 = 0;
            cardEatedIndex2 = 0;
            cardEatedIndex3 = 0;
            isFinishGame = true;
            isDrawResult = true;
            parent.repaint();
            return;
        }

        if (part[0].equals("DB")) {
            try {
                playerFightid = Integer.parseInt(part[1]);
//            Debug.d("player fight id :" + playerFightid);
                if (isViewer) {
                    gameTurn = playerFightid;
                }
                timeForThink = TIME_FOR_THINK;
                isDrawClock = true;
                if (playerFightid != playerId || isViewer) {
                    int cardFightId = Integer.parseInt(part[2]);
                    cardCanbeEated = new Card(cardFightId, Card.STATE_NORMAL, cardImages);
                    addCardToFightedList(cardCanbeEated, playerFightid);
                    nextGameTurn();
                }
                return;
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        if (part[0].equals("UPAS")) {
            gameData.setTablePass(part);
            return;
        }
        if (part[0].equals("EA")) {
            playerFightid = Integer.parseInt(part[1]);
            if (gameTurn != playerId || isViewer) {
                processEaMessage();
                return;
            }

        }
        if (part[0].equals("HP")) {
            //hp|palyerId|cardId|cardId...
            int playerHaPhomId = Integer.parseInt(part[1]);
            if (playerId != playerHaPhomId || isViewer) {
                int phomLength = part.length - 2;
                int[] cardReceiveId = new int[phomLength];
                for (int i = 0; i < phomLength; i++) {
                    cardReceiveId[i] = Integer.parseInt(part[i + 2]);
                    Debug.d("card ha phom :" + cardReceiveId[i]);
                }
                movePhomSet(cardReceiveId, phomLength, playerHaPhomId);
            }
            return;
        }
        if (part[0].equals("DL")) {
            playerDenLang = Integer.parseInt(part[2]);
            playerWinByUId = Integer.parseInt(part[1]);
            Debug.d("player u :" + playerWinByUId);
            isFinishGame = true;
            isDrawResult = true;
            parent.repaint();
            return;
        }
        if (part[0].equals("FS")) {
            if (isViewer) {
                resetGameForViewer();
            }
            return;
        }
        if (part[0].equals("SE")) {
            isLoading = false;
            gameData.setNumberPlayerInTable(part);
            showChooseTable();
            isGoBack = true;
            parent.repaint();
            return;
        }
        if (part[0].equals("SM")) {
            gameData.setTableMoneyBet(part);
            return;
        }

        if (part[0].equals("RO")) {
            gameData.setRoArrData(part);
            if (numberPlayers == 1) {
                isFinishGame = true;
                isDrawResult = true;
            }
            if (!gameData.isPlays[gameTurn]) {
                timeForThink = TIME_FOR_THINK;
                isDrawClock = true;
                nextGameTurn();
                int numberPlayerFinish = countPlayerFinish();
                if (numberPlayerFinish == numberPlayers && gameTurn == playerId) {
                    Request.fnMessgePhom();
                    isFinishGame = true;
                }
            }
            if (numberPlayers < maxPlayer && isViewer) {
                isShowJoin = true;
            }
            Debug.d("is show menu  :" + isShowSubMenu);
            parent.repaint();
            return;
        }
        if (part[0].equals("RE")) {
            gameData.setReArrData(part);
            // khi add vao roi ma ko gui JS ve
            if (isShowJoin && !isViewer) {
                showWaitingRoom();
                isLoading = false;
                parent.repaint();
                isGoBack = true;
            }
            if (isViewer) {
                isLoading = false;
                isGoBack = true;
            }
            return;
        }
        if (part[0].equals("CM")) {
            try {
                int money = Integer.parseInt(part[2]);
                int id = Integer.parseInt(part[1]);
                int posId = (id - playerId + maxPlayer) % maxPlayer;
                gameData.changeMoney(id, money);
                switchMoneyChange(posId, part[2]);
                //  startTimeChat[posId] = System.currentTimeMillis();
                parent.repaint();
            } catch (Exception ex) {
                ex.printStackTrace();
            }
            return;
        }

        if (part[0].equals("JS")) {
            int joinResult = Integer.parseInt(part[1]);
            if (joinResult == 0) {
                isLoading = false;
                isShowJoin = false;
                dialogString = "Bàn đã đủ người chơi";
                isJoinedGame = false;
            } else {
                isJoinedGame = true;
                isLoading = false;
                dialogString = "Bạn sẽ tham gia ở ván sau";
            }
            parent.repaint();
            return;
        }
        if (part[0].equals("MO")) {
            gameData.setMoArrData(part);
            parent.repaint();
            return;
        }

        if (part[0].equals("INFO")) {
            gameData.setInfoData(part);
//            isViewer = (myViewId < maxPlayer ? false : true);
//            if (!isViewer) {
//                showWaitingRoom();
//            }
            parent.repaint();
            return;
        }
        if (part[0].equals("GUI")) {
            int fromPlayId = Integer.parseInt(part[1]);
            int toPlayerId = Integer.parseInt(part[2]);
            int cardId = Integer.parseInt(part[3]);
            int posType = Integer.parseInt(part[4]);
            if (fromPlayId != playerId || isViewer) {
                addDepositCardToPhom(fromPlayId, toPlayerId, cardId, posType);
            }
            return;
        }
        if (part[0].equals("CHAT")) {
            int postId = (Integer.parseInt(part[2]) - playerId + maxPlayer) % maxPlayer;
            if (postId != 0) {
                switchMessengerBox(postId, part[1]);
                parent.repaint();
            }
            return;
        }
    }

    private void resetGameForViewer() {
        isFinishGame = false;
        isDrawResult = false;
        cardEatedIndex0 = 0;
        cardEatedIndex1 = 0;
        cardEatedIndex2 = 0;
        cardEatedIndex3 = 0;
        for (int i = 0; i < 4; i++) {
            phomCardIndex[i] = 0;
            cardFightedIndex[i] = 0;
            cardRemainIndex[i] = 0;
        }
        countFnReceive = 0;
        parent.repaint();
    }
}
